tags:

views:

112

answers:

1

I have Javascript that imputes (computes and injects) HTML into my DOM for the Facebook "Like" function. I need to specify a "canonical" URL because the actual URL doesn't reflect all the DOM manipulations that have been made (driven by user activity on the Web "page"). Alas, Facebook's code doesn't use the url I supply but the window.location value (which has #hash aspects that influence the page's presentation, but that aren't accessible to the server). Anyway... why is FB's code ignoring the url I give to it?

I generate the HTML thus:

var html = '<iframe src="http://www.facebook.com/plugins/like.php?href=' + encodeURI(url) + '&layout=standard&show_faces=false&width=100&action=recommend&font=arial&colorscheme=light" style="border:none; overflow:hidden; width:270px; height:26px;" allowTransparency="true" frameborder="0" scrolling="no"></iframe>'

+1  A: 

encodeURI is the wrong method here. It only encodes characters that are totally invalid to be in a URL at all; it leaves alone characters that may be in a URL but have a special meaning. So:

'?par1='+encodeURI('http://example/scr?par2=2&amp;par3=3')

ends up as:

'?par1=http://example/scr?par2=2&amp;par3=3'

and the & character acts as a parameter separator for the outer URL inside of the inner one, prematurely ending the URL parameter you were passing to Facebook.

For a query parameter name/value or a path part, the correct function is encodeURIComponent().

Also, you are creating invalid HTML by not escaping your ampersands in the attribute value. If you must create HTML in a string(*) you will need an HTML-encoder:

function encodeHtml(s) {
    return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/"/g, '&quot;');
}

var fburl= (
    'http://www.facebook.com/plugins/like.php'+
    '?action=recommend&href='+encodeURIComponent(url)+
    '&layout=standard&show_faces=false&width=100&font=arial&colorscheme=light'
);
var html= (
    '<iframe src="'+encodeHtml(fburl)+'" '
    'allowTransparency="true" frameborder="0" scrolling="no" '+
    'style="border:none; overflow:hidden; width:270px; height:26px;">'+
    '</iframe>'
);

(*: and normally I'd try to avoid that, preferring to use DOM methods to create element content, since then you don't have to worry about HTML-escaping.)

bobince
Thanks for the sharing your insights. I do use DOM methods to "inject" the HTML into the DOM. I believe the source of my troubles was in not using encodeURIComponent() to generate the fburl.
Zhami
(I was thinking of DOM methods like `createElement` and properties like `iframe.src= fburl;`. But yeah, the name of `encodeURI` is a bit misleading.)
bobince

related questions