简体   繁体   中英

Why does this cross-domain request workaround work?

In this John Resig article , he's is dealing with a dictionary-sized list of words with javascript, and he's loading the content via ajax from a CDN.

The words are loaded in with newlines separating the words. Then he says cross domain fails:

There's a problem, though: We can't load our dictionary from a CDN! Since the CDN is located on another server (or on another sub-domain, as is the case here) we're at the mercy of the browser's cross-origin policy prohibiting those types of requests. All is not lost though - with a simple tweak to the dictionary file we can load it across domains.

First, we replace all endlines in the dictionary file with a space. Second, we wrap the entire line with a JSONP statement. Thus the final result looks something like this:

dictLoaded('aah aahed aahing aahs aal... zyzzyvas zzz');

This allows us to do an Ajax request for the file and have it work as would expected it to - while still benefiting from all the caching and compression provided by the browser.

So, if I'm reading this correctly, simply adding his method dictLoaded('original content') around the original content alone causes the ajax request to not fail.

Is that (turning it into a function + param) really all it takes? and why does JSONP solve the problem of cross domain access restriction?

the <script> tags can load any JS file from anywhere (even cross domain). The nice thing that comes with it is that the code inside that script is also executed, therefore, a method of bypassing cross-domain restrictions.

The problem is, when the code gets executed, it's executed in the global scope. so having this code:

var test = 'foo'

will create a test variable in the global scope.

To mitigate this, you use enclose the reply in a function. This is the "P" in "JSONP" which means "padding". This encloses your reply in a function call.

So if your foreign script has:

myFunction({
    test : 'foo'
});

It calls myFunction and passes an object with test key which has value foo . The receiving function would look like:

function myFunction(data){
    //"data.test" is "foo"
}

Now we have successfully bypassed the cross-domain restriction. The essential parts needed are:

  • the receiving function (which can be dynamically created and discarded after use)
  • the "padded" JSON reply

It is because of the JSONP statement that he added.

"JSON with padding" is a complement to the base JSON data format. It provides a method to request data from a server in a different domain, something prohibited by typical web browsers because of the Same origin policy.

This works via script element injection.

JSONP makes sense only when used with a script element. For each new JSONP request, the browser must add a new element, or reuse an existing one. The former option - adding a new script element - is done via dynamic DOM manipulation, and is known as script element injection. The element is injected into the HTML DOM, with the URL of the desired JSONP endpoint set as the "src" attribute. This dynamic script element injection is usually done by a javascript helper library. jQuery and other frameworks have jsonp helper functions; there are also standalone options.

Source: http://en.wikipedia.org/wiki/JSONP

Is that (turning it into a function + param) really all it takes?

Yes.

and why does that solve the problem of cross domain access restriction?

You should read about JSONP . The idea is that you can now include a <script> tag dynamically pointing to the resource instead of sending an AJAX request (which is prohibited). And since you have wrapped the contents with a function name, this function will be executed and passed as argument the JSON object. So all that's left for you is to define this function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM