I have JavaScript that 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>'
encodeURIis 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:ends up as:
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:
(*: 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.)