Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Register now to learn Fabric in free live sessions led by the best Microsoft experts. From Apr 16 to May 9, in English and Spanish.

Reply
ajhops
Frequent Visitor

Integrate tile into an app sample javascript error.

Following the steps in the sample here: https://powerbi.microsoft.com/en-us/documentation/powerbi-developer-integrate-tile/

 

In the final step, load the tile into an iFrame I have a problem posting the messageStructure to the iframe source. 

var messageStructure = {
        action: "loadTile",
        accessToken: document.getElementById('MainContent_accessToken').value,
        height: 500,
        width: 500
    };
    message = JSON.stringify(messageStructure);

    // Push the message
    document.getElementById('iFrameEmbedTile').contentWindow.postMessage(message, "*");;

 

A Javascript error occurs in powerbivisualrenderer.min.js when the atob method is called on a string that is not base64 encoded. My hunch is that the access token is supposed to be a valid base64 string. I verified that by passing in a valid base64 string in the accessToken variable, and the error ceased (but of course I got a 403 forbidden). 

 

My access token is 1475 characters long with no "=" sign at the end and is definitely not a base64 encoded string. The access token is working everywhere else in that example in the server side code when sent in the authorization header. 

 

So, is the accessToken supposed to be a Base64 encoded string? If not, what would cause this error:

 

caught DOMException: Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.
at T (https://app.powerbi.com/13.0.1700.1256/scripts/powerbivisualrenderer.min.js:2:16257)
at Object.success (https://app.powerbi.com/13.0.1700.1256/scripts/powerbivisualrenderer.min.js:2:10067)
at j (https://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.1.min.js:2:26860)
at Object.fireWith [as resolveWith] (https://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.1.min.js:2:27673)
at x (https://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.1.min.js:4:11120)
at XMLHttpRequest.<anonymous> (https://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.1.min.js:4:14767)

7 REPLIES 7
Eric_Zhang
Employee
Employee

@ajhops

I don't experience that error. My token is a long string starts with "eyJ0eX....". Here is a static HTML which works perfect in my test, just replace the embed url and token with the ones in your case.

 

 

<html lang="en">
<head> 
    <script type="text/javascript">

        window.onload = function () {
		
		updateEmbedTile(); 
        };

        var width = 500;
        var height = 500; 

        // update embed tile
        function updateEmbedTile() {
            // replace your embed url here
            var embedTileUrl = "https://app.powerbi.com/embed?dashboardId=f1f5155b-c6e2-4147-991b-28d914927d05&tileId=2dcd2a32-725e-4454-9753-b3e01e41a4a1";
            if ("" === embedTileUrl)
                return;

            // to load a tile do the following:
            // 1: set the url, include size.
            // 2: add a onload handler to submit the auth token
            iframe = document.getElementById('iFrameEmbedTile');
            iframe.src=embedTileUrl + "&width=" + width + "&height=" + height;
            iframe.onload = postActionLoadTile;
        }

        
        // post the auth token to the iFrame. 
        function postActionLoadTile() {
            // replace your token here
            accessToken = "eyJ0eXAiOiJKV....kGoJT_tGqBbsXCv60YIXJZTdheFAiwFw";

            // return if no a
            if ("" === accessToken)
                return;

            var h = height;
            var w = width; 

            // construct the push message structure
            var m = { action: "loadTile", accessToken: accessToken, height: h, width: w};
            message = JSON.stringify(m);

            // push the message.
            iframe = document.getElementById('iFrameEmbedTile');
            iframe.contentWindow.postMessage(message, "*");;
        }

    </script>
</head>
<body>

<iframe ID="iFrameEmbedTile" src="" height="500px" width="500px" frameborder="0" seamless></iframe>

 
</body>
</html>

 

Thank you for your reply! I still get the same error. My access token also starts with "eyJ0eXAiOiJ" and is very long. There are no new lines in the string and no whitespace. Can you do me one quick favor and open your browser developer console and execute:

 

atob("YOUR_ACCESS_TOKEN")

and tell me if you get an error. 

@ajhops

 

I've got the same error, however I can still embed with that token. 

 

Capture.PNG

 

Embedding is working fine with the HTML in my previous reply. All responses 200(ok).

Capture2.PNG

 

Not sure if it is the issue of the cluster node, will you try to replace the app.powerbi.com in the embed url with below IP, it is the actual remote server in my test, captured from the chrome dev tool.

https://13.78.91.196/embed?dashboardId=f1f5155bxxxxx914927d05&tileId=2dcd2a32-725e-4454-9753-b3

 

@Eric_Zhang

 

When I try that IP address I get insecure response:

InsecureResponse.PNG

 

I also get all 200s but the tile never appears (only the spinning dots) and the JS error every time. The remote server I am hitting is  137.116.81.69:443.

200s.PNG

 

@ajhops

Have you tested with my HTML? What's going on when in IE, do you still get the atob error? May I know how you generate the accessToken?

@Eric_Zhang 

 

When I run in IE I get "InvalidCharacterError". I believe this is the same error as before. 

 

Capture.PNG

 

To answer your question, yes I am using your static HTML but replace with my token and tile URL. I generate my access token on my back end (.net MVC) using this line:

 

var ar = AC.AcquireTokenByAuthorizationCodeAsync(
                authorizationCode,
                new Uri(redirectUri), cc).Result;

   
return ar.AccessToken;

I later use that access token server side to get my list of dashboards and tiles, and the result is good, so I assume my token is good / correct (the variable _token below). 

 

System.Net.WebRequest request = System.Net.WebRequest.Create(
                String.Format("{0}Dashboards", _baseUri
                )) as System.Net.HttpWebRequest;

request.Method = "GET";
request.ContentLength = 0;
request.Headers.Add("Authorization", String.Format("Bearer {0}", _token));

@ajhops

Well, then I suggest you open a support ticket.

Helpful resources

Announcements
Microsoft Fabric Learn Together

Microsoft Fabric Learn Together

Covering the world! 9:00-10:30 AM Sydney, 4:00-5:30 PM CET (Paris/Berlin), 7:00-8:30 PM Mexico City

PBI_APRIL_CAROUSEL1

Power BI Monthly Update - April 2024

Check out the April 2024 Power BI update to learn about new features.

April Fabric Community Update

Fabric Community Update - April 2024

Find out what's new and trending in the Fabric Community.

Top Kudoed Authors