Kategorien
TypeScript

Cross Domain AJAX Requests: Embedding content from another domain via JavaScript, jQuery and JSONP

Integrating content from a domain B into content at domain A using JavaScript and jQuery is not too easy. Due to the „same domain“ policy, all modern browsers prohibit simply calling jQuery’s $.load() function. The problem continues if you want to submit form data to another domain.

Situation:

  • Website hosted at Domain A.
  • Website at Domain A loads some JavaScript from Domain B which should render a form into the content of Domain A and submit the form data to Domain B.

In short, there are two opportunities to solve this issues:

  1. Send a „Access-Control-Allow-Origin“-HTTP-Header along with the resources delivered from Domain B. This header is part of the Cross-Origin Ressource Sharing (CORS) Concept introduced by the W3C. However, this works with really modern browsers only (Internet Explorer 9, Firefox 3.5, Opera 12, Chrome), so it’s not suitable for most situations.
  2. Use JSONP. This works with all browsers I have tested so far (IE 6+, Firefox, Chrome, Safari, …).

I’ll focus on JSONP here.

Let’s have a look at how JSONP works:

Instead of simply sending an AJAX XMLHttpRequest via $.load() from Domain A to Domain B, JSONP adds a <script> tag to the HTML DOM of Domain A’s website. The script’s source is a JavaScript file you’re loading from Domain B. Domain B sends back a JavaScript which initiates a function call with a JSON encoded object as its parameter. The function was set up dynamically, so when the response from Domain B is received, the function call can be executed.

Have a look at this in detail:

Somewhere in the HTML DOM of Domain A, you’re placing a container for the content to be loaded from Domain B:

The source.js at Domain B contains something like this (note the callback=? parameter – it’s important to get JSONP to work):

$.getJSON('http://domain-A/gethtml.php?callback=?', {}, function(json) {
    $('#container').html(json['result']);
});

The file gethtml.php is responsible for delivering the HTML content that is to be embedded into the #container-DIV:

That’s it. What’s inconvenient is that you need a JSONP wrapper for delivering the content that is to be embedded. If you now want to send the user’s input into the form you loaded to Domain B, you use quite the same mechanism (assuming idName and idMail are form input fields):

var data = {'name': $('#idName').val(), 'mail': $('#idMail').val()};
$.getJSON('http://domain-B/handler.php?callback=?', data, function(json) {
    // Do something with the response...
});

Here are some more test results on cross domain ajax requests (tested in Chrome):

Domain ADomain BResult
Embed file from Domain B via $.load()Not allowed
Embed a script from Domain B via <script>In script: Embed file from Domain B via $.load()Not allowed
Embed a script from Domain B via <script>In script:Create DOM elements for form manually in site of Domain AAllowed
Embed a script from Domain B via <script>As above, and send form data to Domain B via $.getJSON() without using JSONPNot allowed
Embed a script from Domain B via <script>As above, but use JSONP insteadAllowed
Embed a script from Domain B via <script>In script: Load html to embed into site of Domain A via $.getJSON() via JSONP and use JSONP to send form data to Domain BAllowed

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.