pinterest / widgets

JavaScript widgets, including the Pin It button.
Other
211 stars 88 forks source link

pinit_main.js causing 404 errors #22

Closed dan-silk-discovery closed 10 years ago

dan-silk-discovery commented 10 years ago

As far as I can tell, it looks like there's code in this file that is supposed to create another script tag for this URL:

http://widgets.pinterest.com/v1/urls/count.json?url=http%3A//www.food.com/slideshow/recipe-of-the-day-325&ref=http%3A%2F%2Fwww.food.com%2Fslideshow%2Frecipe-of-the-day-325%2Fjan-27-pickle-wrap-dip-27%3Foc%3Drotd&source=6&callback=PIN_1390879344178.f.callback[0]

The problem is, the URL has my domain concatenated with this URL so it looks like this:

http://www.food.com/slideshow/recipe-of-the-day-325/http://widgets.pinterest.com/v1/urls/count.json?url=http%3A//www.food.com/slideshow/recipe-of-the-day-325&ref=http%3A%2F%2Fwww.food.com%2Fslideshow%2Frecipe-of-the-day-325%2Fjan-27-pickle-wrap-dip-27%3Foc%3Drotd&source=6&callback=PIN_1390879344178.f.callback[0]

This happens multiple times on the page; another URL that is malformed is:

http://www.food.com/slideshow/recipe-of-the-day-325/http://log.pinterest.com/?via=http%3A%2F%2Fwww.food.com%2Fslideshow%2Frecipe-of-the-day-325%2Fjan-27-pickle-wrap-dip-27%3Foc%3Drotd&guid=zN6MCy2_bu8h&type=pidget&callback=PIN_1390879344178.f.callback[1]

Since I don't have unminimized source code for pinit_main.js, it's fairly difficult to debug so I'm hoping you have some insight into the issue. Can you look into this to find out what's causing the formation of the bad URL?

This is one of the pages where it's happening for your reference:

http://www.food.com/slideshow/recipe-of-the-day-325/jan-27-pickle-wrap-dip-27?oc=rotd

Thanks!

kentbrew commented 10 years ago

Terribly sorry about the delay; source has been updated.

kentbrew commented 10 years ago

This may not be what's broken but it appears your page may not be properly percent-encoding forward-slashes in the URLs that it's sending to the Pin It button. I'm seeing examples like this:

http://www.pinterest.com/pin/create/button/?url=http%3A//www.food.com/slideshow/recipe-of-the-day-325&media=http%3A//pictures.food.com/api/file/9s4q3IDARn2nVsUqFLAP-Jan-27-Pickle-Dip.jpg/convert%3Floc%3D/pictures.food.com/slideshow-item/0325/10yfu7iETQuk3JqQf34G_Jan%252027%2520Pickle%2520Dip.jpg%26width%3D293%26height%3D273%26fit%3Dcrop&guid=MxCrnppqcobL-0&description=Feast+your+eyes+on+a+daily+dose+of+our+home+cooks%27+top-rated+recipes+%28and+fantastic+food+photos%21%29.

Forward-slashes should show as %2F.

kentbrew commented 10 years ago

Looks like we are double-prepending window.location.protocol to all of our API endpoints for your site only. When I look at $.a.endpoint after your page renders I am seeing http:http:// on top of everything; when I look at other sites (like our Widget Builder) I don't see this.

One quick way to check this would be to comment out line 1301 in pinit_main.js; it's the one that prepends window.location.protocol to all endpoints so testing by dragging a file into a browser window is possible.

kentbrew commented 10 years ago

Also it looks like you are loading pinit_main.js directly from your HEAD; this is not guaranteed to work if your BODY takes too long to render.

dan-silk-discovery commented 10 years ago

Thanks for getting back to me! I'll try debugging pinit_main.js like you said. Should I load that at the bottom of the body instead of the head?

kentbrew commented 10 years ago

We are seeing best results from sites that load a single copy of pinit.js from the bottom of their BODY tag, like this:

<script src="//assets.pinterest.com/js/pinit.js" async type="text/javascript"></script>

This is the best way to be sure the entire BODY has made it out onto the wire before calling third-party JavaScript. Another way to load third-party JavaScript is with an asynchronous loader, like this:

<script type="text/javascript">
(function(d){
    var f = d.getElementsByTagName('SCRIPT')[0], p = d.createElement('SCRIPT');
    p.type = 'text/javascript';
    p.async = true;
    p.src = '//assets.pinterest.com/js/pinit.js';
    f.parentNode.insertBefore(p, f);
}(document));
</script>

Asynch loaders can be called from anywhere on the page, including the HEAD.

dan-silk-discovery commented 10 years ago

We're loading it async using jQuery DOMready, just putting it in the head tag. So technically, all the elements necessary for the pinit button will be in the page by the time the script tag is added.

kentbrew commented 10 years ago

Has this settled down for you? Please reopen if not.

dan-silk-discovery commented 10 years ago

Honestly, I haven't noticed, but since no one is complaining about it here, I'd say keep it closed. Thanks!