Reputation: 1151
This code is just stuck in the Body it does exactly what I expect but I don't understand WHY.
Particularly I dont see how the webservice gets called, it looks like the script adds the call to the Head section and maybe reloads the page but I'm not sure and don't like not knowing or what this line means - script.onload = script.onreadystatechange = function ()
Can anyone explain please?
var script = document.createElement("script"),
head = document.getElementsByTagName("head")[0],
url = "https://services.postcodeanywhere.co.uk/PostcodeAnywhere/Interactive/FindByPostcode/v1.00/json.ws?";
// Build the query string
url += "&Key=" + encodeURI(pca_Key);
url += "&Postcode=" + encodeURI(postcode);
url += "&CallbackFunction=PostcodeAnywhere_FindByPostcode_End";
script.src = url;
// Make the request
script.onload = script.onreadystatechange = function () {
if (!this.readyState || this.readyState === "loaded" || this.readyState === "complete") {
script.onload = script.onreadystatechange = null;
if (head && script.parentNode)
head.removeChild(script);
}
}
head.insertBefore(script, head.firstChild);
Stu
Upvotes: 1
Views: 312
Reputation: 1074295
Basically, it's making a JSONP call to get some data from postcodeanywhere.co.uk. JSONP uses script
elements. The script from postcodeanywhere.co.uk will call the function identified by the CallbackFunction
argument on the script URL, passing it a JavaScript object literal, something like this:
PostcodeAnywhere_FindByPostcode_End({
name: value
})
You haven't shown it, but presumably there's a function with that name defined at global scope in the script making the call.
This is to work around the SOP, which doesn't allow ajax calls cross-origin.
How it does it is by creating a script
element, assigning it the src
URL, appending it to the page, and then hooking the readystate
event so it can clean up after itself by removing the element again. (That last bit isn't quite what it could be, not all browsers fire the readystate
event on script
elements, to do this thoroughly you have to hook both readystate
and load
. Or do the cleanup in the callback. But having the script element lying around is harmless.) It should also be using encodeURIComponent
, not encodeURI
. And there's no need for the stuff with the head
element, you can just append the script directly to document.documentElement
.
Upvotes: 6
Reputation: 340733
This script grammatically creates <script/>
HTML tag with given src
URL and appends it to the beginning of the <head>
in the page DOM:
<head>
<script src="https://services.postcodeanywhere.co.uk/PostcodeAnywhere/Interactive/FindByPostcode/v1.00/json.ws?&Key=...&Postcode=...&Postcode="></script>
<!-- the rest of the HEAD -->
</head>
It also attaches event handler to both onload
and onreadystatechange
. This event is triggered when the script is loaded. Interestingly, it removes the event handler and the <script/>
tag once it is loaded, cleaning up after itself.
Probably the script runs some code immediately after being downloaded for its side-effects. E.g. it creates a global object or modifies the DOM. Once the script is done, it is removed for some reason.
Upvotes: 3
Reputation: 9130
1) It creates a DOM element,
2) puts it in the head element, thus downloads it.
3) Executes it
4) Removes the DOM element.
Note that any global functions and variables will be available later, so code from it could be executed, and variables accessed after it is removed.
Upvotes: 2