FB.ui does not work the first time. Help! - javascript

I created an app which publishes to the user's wall. The problem is, the first time the user accesses the page, the FB.ui doesn't show up. After one reload, it works perfectly.
by first time, I mean when the user gives permissions to the app, OR when he has already given permissions. In both scenarios, the problem occurs. Any ideas, people?
FB.init({
appId : "XXXX",
status : true,
xfbml : true,
cookie : true
});
FB.ui(
{
method: 'stream.publish',
message: 'test message'
}
);

This is a frequent problem in JS, with things like trying to calculate how far an item has moved, and it only starts counting after the first iteration.
You need to wrap your js in window.onload = function() {
}
Although this is buggy cross-browser, and may not fix issue. Have you heard of jQuery, its:
$(document).ready(function() {
}
If a very robust solution to ths problem

Comment #70 by Will Kessler at: http://bugs.developers.facebook.net/show_bug.cgi?id=12849 fixed my problem. It's a hack, but it works perfectly :) I had another bug related to this ( FB.ui does not work inside FB canvas. HELP!) , and it also was fixed using this. FB API is seriously buggy! :|

Related

How to properly use jQuery.sap.log.debug instead of console.log in SAPUI5 v.1.38.39?

About environment:
The used framework: SAPUI5
version: 1.38.39
development environment: sap web-ide
reproductible with OpenUI5 v.1.38
About Issue :
Recommendation from UI5 : to don't use console.log("message")
Proposition from UI5: use jQuery.sap.log.debug("message") instead, documentation here
expected result : see the "message" in the console from chrome debugger"
actual result : Don't see the "message" in the console"
Code part :
on my controller :
onInit: function(){
jQuery.sap.log.debug('onInit fired'); // display nothing in chrome console
console.log('onInit fired'); // display "onInit fired" in chrome console
},
Question:
Does someone has a solution or idea for solve this problem ?
Remark:
My question is probably simple, but i didn't find any solution
nowhere, and I am new to UI5, so I am asking here, thank you for your help and
comprehension.
If someone also can tell me why this question (the only one I asked so far) lock me to ask further questions, I think the post respect this ? Thank you for your feedback
Did you set the log level to DEBUG?
If not try to add :
jQuery.sap.log.setLevel(jQuery.sap.log.Level.DEBUG)
Also, is there any particular reason you are using 1.38 and not something more recent?

Failed to execute 'postMessage' on 'DOMWindow': https://www.youtube.com !== http://localhost:9000

This is the error message that I get:
Failed to execute 'postMessage' on 'DOMWindow': The target origin provided
('https://www.youtube.com') does not match the recipient window's origin
('http://localhost:9000').
I've seen other similar problems where the target origin is http://www.youtube.com and the recipient origin is https://www.youtube.com, but none like mine where the target is https://www.youtube.com and the origin is http://localhost:9000.
I don't get the problem. What is the problem?
How can I fix it?
I believe this is an issue with the target origin being https. I suspect it is because your iFrame url is using http instead of https. Try changing the url of the file you are trying to embed to be https.
For instance:
'//www.youtube.com/embed/' + id + '?showinfo=0&enablejsapi=1&origin=http://localhost:9000';
to be:
'https://www.youtube.com/embed/' + id + '?showinfo=0&enablejsapi=1&origin=http://localhost:9000';
Just add the parameter "origin" with the URL of your site in the paramVars attribute of the player, like this:
this.player = new window['YT'].Player('player', {
videoId: this.mediaid,
width: '100%',
playerVars: {
'autoplay': 1,
'controls': 0,
'autohide': 1,
'wmode': 'opaque',
'origin': 'http://localhost:8100'
},
}
Setting this seems to fix it:
this$1.player = new YouTube.Player(this$1.elementId, {
videoId: videoId,
host: 'https://www.youtube.com',
You can save the JavaScript into local files:
https://www.youtube.com/player_api
https://s.ytimg.com/yts/jsbin/www-widgetapi-vfluxKqfs/www-widgetapi.js
Into the first file, player_api put this code:
if(!window.YT)var YT={loading:0,loaded:0};if(!window.YTConfig)var YTConfig={host:"https://www.youtube.com"};YT.loading||(YT.loading=1,function(){var o=[];YT.ready=function(n){YT.loaded?n():o.push(n)},window.onYTReady=function(){YT.loaded=1;for(var n=0;n<o.length;n++)try{o[n]()}catch(i){}},YT.setConfig=function(o){for(var n in o)o.hasOwnProperty(n)&&(YTConfig[n]=o[n])}}());
Into the second file, find the code: this.a.contentWindow.postMessage(a,b[c]);
and replace it with:
if(this._skiped){
this.a.contentWindow.postMessage(a,b[c]);
}
this._skiped = true;
Of course, you can concatenate into one file - will be more efficient.
This is not a perfect solution, but it's works!
My Source : yt_api-concat
Make sure you are loading from a URL such as:
https://www.youtube.com/embed/HIbAz29L-FA?modestbranding=1&playsinline=0&showinfo=0&enablejsapi=1&origin=https%3A%2F%2Fintercoin.org&widgetid=1
Note the "origin" component, as well as "enablejsapi=1". The origin must match what your domain is, and then it will be whitelisted and work.
In my case this had to do with lazy loading the iframe. Removing the iframe HTML attribute loading="lazy" solved the problem for me.
I got the same error. My mistake was that the enablejsapi=1 parameter was not present in the iframe src.
You also get this message when you do not specify a targetOrigin in calls to window.postMessage().
In this example we post a message to the first iFrame and use * as target, which should allow communication to any targetOrigin.
window.frames[0].postMessage({
message : "Hi there",
command :"hi-there-command",
data : "Some Data"
}, '*')
Try using window.location.href for the url to match the window's origin.
Remove DNS Prefetch will solve this issue.
If you're using WordPress, add this line in your theme's functions.php
remove_action( 'wp_head', 'wp_resource_hints', 2 );
There could be any of the following, but all of them lead into DOM not loaded before its accessed by the javascript.
So here is what you have to ensure before actually calling JS code:
* Make sure the container has loaded before any javascript is called
* Make sure the target URL is loaded in whatever container it has to
I came across the similar issue but on my local when I am trying to have my Javascript run well before onLoad of the main page which causes the error message. I have fixed it by simply waiting for whole page to load and then call the required function.
You could simply do this by adding a timeout function when page has loaded and call your onload event like:
window.onload = new function() {
setTimeout(function() {
// some onload event
}, 10);
}
that will ensure what you are trying will execute well after onLoad is trigger.
In my instance at least this seems to be a harmless "not ready" condition that the API retries until it succeeds.
I get anywhere from two to nine of these (on my worst-case-tester, a 2009 FossilBook with 20 tabs open via cellular hotspot).... but then the video functions properly. Once it's running my postMessage-based calls to seekTo definitely work, haven't tested others.
It looks it's only a Chrome security system to block repeated requests, using CORB.
https://www.chromestatus.com/feature/5629709824032768
In my case, YouTube was blocking Access after the first load of the same webpage which has many video API data request, high payload.
For pages with low payload, the issue does not occur.
In Safari and other non Chronuim based browsers, the issue does not occur.
If I load the webpage in a new browser, the issue does not occur, when I reload the same page, the issue appears.
In some cases (as one commenter mentioned) this might be caused if you are moving the player within DOM, like append or etc..
This helped me (with Vue.js)
Found here vue-youtube
mounted() {
window.YTConfig = {
host: 'https://www.youtube.com/iframe_api'
}
const host = this.nocookie ? 'https://www.youtube-nocookie.com' : 'https://www.youtube.com'
this.player = player(this.$el, {
host,
width: this.width,
height: this.height,
videoId: this.videoId,
playerVars: this.playerVars
})
...
}
UPDATE:
Working like a charm like this:
...
youtube(
video-id="your_video_code_here"
nocookie
)
...
data() {
return {
playerVars: {
origin: window.location.href,
},
};
},
I think the description of the error is misleading and has originally to do with wrong usage of the player object.
I had the same issue when switching to new Videos in a Slider.
When simply using the player.destroy() function described here the problem is gone.
I had this same problem and it turns out it was because I had the Chrome extension "HTTPS Everywhere" running. Disabling the extension solved my problem.
This exact error was related to a content block by Youtube when "playbacked on certain sites or applications". More specifically by WMG (Warner Music Group).
The error message did however suggest that a https iframe import to a http site was the issue, which it wasn't in this case.
You could change your iframe to be like this and add origin to be your current website. It resolves error on my browser.
<iframe class="test-testimonials-youtube-group" type="text/html" width="100%" height="100%"
src="http://www.youtube.com/embed/HiIsKeXN7qg?enablejsapi=1&origin=http://localhost:8000"
frameborder="0">
</div>
ref: https://developers.google.com/youtube/iframe_api_reference#Loading_a_Video_Player
Just wishing to avoid the console error, I solved this using a similar approach to Artur's earlier answer, following these steps:
Downloaded the YouTube Iframe API (from https://www.youtube.com/iframe_api) to a local yt-api.js file.
Removed the code which inserted the www-widgetapi.js script.
Downloaded the www-widgetapi.js script (from https://s.ytimg.com/yts/jsbin/www-widgetapi-vfl7VfO1r/www-widgetapi.js) to a local www-widgetapi.js file.
Replaced the targetOrigin argument in the postMessage call which was causing the error in the console, with a "*" (indicating no preference - see https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage).
Appended the modified www-widgetapi.js script to the end of the yt-api.js script.
This is not the greatest solution (patched local script to maintain, losing control of where messages are sent) but it solved my issue.
Please see the security warning about removing the targetOrigin URI stated here before using this solution - https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
Patched yt-api.js example
Adding origin=${window.location.host} or "*" is not enough.
Add https:// before it and it will work.
Also, make sure that you are using an URL that can be embedded: take the video ID out and concatenate a string that has the YouTube video prefix and the video ID + embed definition.
I think we could customize the sendMessage of the YT.Player
playerOptions.playerVars.origin = window.location.origin or your domain.
this.youtubePlayer = new YT.Player(element,playerOptions);
this.youtubePlayer.sendMessage = function (a) {
a.id = this.id, a.channel = "widget", a = JSON.stringify(a);
var url = new URL(this.h.src), origin = url.searchParams.get("origin");
if (origin && this.h.contentWindow) {
this.h.contentWindow.postMessage(a, origin)
}
}
I used this function to resolve in my project.
Extending #Hokascha's answer above it was also lazy loading for me being automatically added by WordPress. This code will remove all lazy loading on the site's iframes (add to functions.php):
function disable_post_content_iframe_lazy_loading( $default, $tag_name, $context ) {
if ( 'iframe' === $tag_name ) {
return false;
}
return $default;
}
add_filter('wp_lazy_loading_enabled', 'disable_post_content_iframe_lazy_loading', 10, 3);
I got a similar error message in my attempt to embed a Stripe pricing table when:
Adding the embed code via PHP through a custom WordPress short code
Or by appending the code to the page dynamically with JavaScript (Even a using a setTimeout() delay to ensure the DOM was loaded didn't work).
I was able to solve this on my WordPress site by adding the code to the WordPress page itself using plain html code in the block editor.
mine was:
<youtube-player
[videoId]="'paxSz8UblDs'"
[playerVars]="playerVars"
[width]="291"
[height]="194">
</youtube-player>
I just removed the line with playerVars, and it worked without errors on console.
You can try :
document.getElementById('your_id_iframe').contentWindow.postMessage('your_message', 'your_domain_iframe')
I was also facing the same issue then I visit official Youtube Iframe Api where i found this:
The user's browser must support the HTML5 postMessage feature. Most modern browsers support postMessage
and wander to see that official page was also facing this issue. Just Visit official Youtube Iframe Api and see console logs. My Chrome version is 79.0.3945.88.

SCRIPT5 : Access is denied on IE-10 after Security Update : jquery-1.4.4.min.js

There was an IE-10 security update on Sept-10. After that, in my application there seems to be an issue accessing a standard div using jquery.
Here is the quick scenario :
I have a jsp layout template where there is a div defined :
<div id="abc"></div>
In that I include a js file k1.js, the following function in that is triggered upon a click of a button
function sample() {
jQuery.get("/fetchmedata.do?a=true", function(data) {
jQuery("#abc").html(data);
});
This was totally functioning across all browsers including ie-10 till Sept -10. After 10th, it still works fine on IE-9 and old IE-10 builds, but on new IE-10 build throws the error in console :
SCRIPT5 : Access is denied
The call stack pointed to internals of Jquery code which I couldn't decipher/understand the context.
The quick fix was to replace the jquery with Javascript, and it worked :
function sample() {
jQuery.get("/fetchmedata.do?a=true", function(data) {
document.getElementById('abc').innerHTML = data;
});
The jquery version was jquery-1.4.4.min.js.
Please advice on what could have been the issue, is it again probably related to not using XDomainRequest instead of XHR, so that we could take precautions in the code to avoid future issues.
Also what is the best practices around it ?
Please advice.

FB.ui dialog for apprequest hangs forever in iframe mode

Somehow I can't get the iframe mode to work in the following code
The dialog shows up but the loading hangs forever and nothing is displayed in the box
it works just fine with display: popup
FB.getLoginStatus(function(resp) {
if (resp.status !== 'connected') return;
FB.ui({
method: 'apprequests',
title: 'My title',
display: 'iframe',
message: 'My message',
to: '100003750613973'
}, function(resp) {
console.log('emitted request to ', resp.to);
});
});
Myself and some of my peers are seeing the same behavior. In our case, the problem seems to happen only when running on a port other than 80. E.g. in development, we usually run on port 3000, and see the hang you describe (with the "feed" dialog in our case). When running on port 80, everything works fine. This appears to be a recent problem.
Haven't used FB.ui in quite a while so not sure how it changed meanwhile, but why do you return console.log()? I'd say, remove the return keyword and try again. See what the Firbug / Chrome / etc. console says. Based on that I'm sure you'll be able to get to a working solution, or post it here and we can help you out. Code should be quite standard.

Calling FB.login with to get permissions throw an error in IE

I'm calling in canvas:
FB.login(function(){}, {
scope:'publish_stream'
});
On Firefox and Chrome shows popup with permission dialog. But on IE there is error (see attach.) :
An error occurred with my_app_name. Please try again later.
My FB.init:
FB.init({
appId: <FB_APP_ID>,
status: true,
cookie: true,
xfbml: true,
oauth: true,
hideFlashCallback: function(){}
});
Earlier (before oauth) I was using code below, it was ok, but it not work wit oauth:
FB.ui({
method: 'permissions.request',
perms: 'publish_stream',
}, function(){});
edit:
Information from access token:
edit2:
If you will find a solution, write answer - if it will work, I'll give you 100 points from my reputation.
To make it work in IE, you should add channelUrl param to your FB.init with fully qualified url. For example:
FB.init({
appId: <FB_APP_ID>,
status: true,
cookie: true,
xfbml: true,
channelUrl: 'http://www.example.com/facebook-channel.html'
});
The url must point to a page that contains just only one script tag:
<script src="http://connect.facebook.net/en_US/all.js"></script>
It's important to make channelUrl an absoulte, if you just write
channelUrl: '/facebook-channel.html'
It wont work. I've got a lot of headache with it, so I hope it'll be helpfull for you or anybody who troubled with it like me before.
Try to switch _inCanvas to true and see what happens
FB._inCanvas = true;
I also had this problem in the past. You are probably opening it on a domain that is not the same as the one specified as your site domain on the application settings page.
If you have selected to use
sandbox
in developers.facebook.com/apps.
You should change it to not use.
Now you’re running on https you will need to reference all assests over https. IE will now show a load of warnings telling the user not all content is sent over the secure connection. This is probably why your popup fails. Set the SDK to load stuff over HTTPS:
FB._https = true;
FB.init({
/* your app id and stuff */
});
maybe it's because IE not setting 3rd party cookies?
try adding
header('P3P: CP=HONK');
into php file, header function has to come before anything in file is output.
I done walkaround for that. I'm opening new window with url like:
https://www.facebook.com/dialog/oauth?client_id=APPID&scope=publish_stream&redirect_uri=MYPAGE
When MYPAGE (which is in my app url) is loaded it simply closes itself.
If you will find a solution, write answer - if it will work, I'll give you 100 points from my reputation.

Categories

Resources