Jquery ajax get data from another domain. Cross-domain ajax with jQuery

December 2 , 2016

I once wrote an article on how to create embeddable widgets in native javascript and php. And everything would be fine, but one moment was not touched upon in it. You can use such widgets on your own site, but it's more interesting to create them for third-party resources. But in this case, the browser must load the necessary data from another domain - these are cross-domain ajax requests.

From a front-end programmer's point of view, cross-domain queries are no different from regular queries. But there is a difference on the backend. Why not everything is so simple with them and how to implement them - read about this in the article.

Trying to get data from another domain

Let's take a look at get requests for simplicity. Let's say there is a certain html file on the server, which we need to load with ajax from another domain .. html. Open it and make sure it is actually available - (opens in a new tab). This is a regular div with the text "content from template.html".

Now let's get this html ajax directly from the browser console.

Let's not bother with native javascript, but jerk the request using jQuery.get () and output to the console what we received in response from the server.

$ .. html ", function (responce) (console.log (responce)));

Open developer tools right now in a browser and in the console tab execute this request.

You will see something like the following

Everything is great, we sent a request, received an answer. It would seem that what could be simpler? Now go to any other site that has jQuery enabled and try the same thing. Just not to the https site, you will find out why at the end of the article.

For example, I checked requests on the football website bombardir.ru. And at the same time he was amazed at what kind of rubbish does not fall out into the console even on such well-known sites. However, the conversation is not about that.

Execute a request from another domain and you will see a not so good picture in the console. He says it is impossible to download, there is no data and generally sadness.

If you open the Network tab and find the corresponding request there, you will see that the server even returned us 200 OK
And there is no file content. What's the catch?

What went wrong and what will be the solution

The catch is that internet policy does not allow browsers to pull data from any resource. Except when these resources are themselves interested in distributing specific data.
Our case is just that. To give permission to use an html file from anywhere, you need to send the Access-Control-Allow-Origin http-header when requesting this file: *

Now the question is how to do it. If you (or the admins) have access to nginx, then one way is to configure the passing of this header by means of a web server. You go to the admins with a request or google the necessary configs for your web server.

If this access is not available, as, for example, with almost any hosting provider at an inexpensive tariff, then you need to get out on your own. This is where php comes in. The idea is to put our html-ku into a php-file, which will throw the header and give the desired content.

It will turn out like this, create the template.php file and write the php command in the first line

Header ("Access-Control-Allow-Origin: *");

Content from template.php

That is, the content of template.php will be like this, do not forget about php questions and brackets

The file on webdevkin is created and is (opens in a new tab). Let's now try to request it from a different domain and see what happens

$ .. php ", function (responce) (console.log (responce)));

As you can see, everything works fine - the file is uploaded!

Let's take a look at the Network tab.
Please note that the Access-Control-Allow-Origin header of interest to us has appeared in the Response Headers block: *

On the whole, the article is over. It remains to collect thoughts in a heap and add some more information.

Summarize and summarize

  • 1. You can't just request ajax for any resource from another domain
  • 2. Send the Access-Control-Allow-Origin header for all resources that need to be accessed from anywhere
  • 3. Do it using a web server or php
  • 4. This header is sent to php by the command header ("Access-Control-Allow-Origin: *")
  • 5. Access-Control-Allow-Origin: * - allow access to all domains, Access-Control-Allow-Origin: site.ru - only the site.ru domain
  • 6. Access-Control-Allow-Origin is sent at the very beginning of the php-file, even before the output of other data (as well as any other http-headers)
  • 7. "Resource" is not only a file with html-markup, but also any url to which an ajax request goes, for example, receiving json data or a post request to add a row to a database table

And the last thing, I took it out separately. It was not in vain that I asked to execute requests from the http-site. With https, you won't be able to load data from http for another reason - mixed content. And the site is still http-site ( updated: no longer, moved the site to https)

Here's what you see in the console when you try to make the same request from any https site. Therefore, if you are going to deal with embedded widgets or something similar, you definitely need to put an ssl certificate on your site.

jQuery.ajax () - makes a request to the server without reloading the page. This is a low-level method with big amount settings. It is at the heart of all ajax, which is often easier to understand and use, but still provides limited functionality compared to this method.

$ .ajax () returns an XMLHttpRequest object. In most cases, you will not need to work directly with this object, but it is still available in case you need to manually interrupt the request.

As an argument to the $ .ajax () function, an object is passed, consisting of key / value pairs that are used to initialize and manipulate the request.

An Ajax request has two use cases:

jQuery.ajax (url [, settings])

The only difference from the previous version of the method is that the url property here is part of the settings, and not a separate parameter.

Settings list

  1. accepts(default: depends on DataType)
    Type: object.
    When a request is made, the headers specify the valid content types expected from the server. Values ​​of these types will be taken from the accepts parameter. For example, the following example specifies valid customtypes:

    $ .ajax ((accepts: (mycustomtype: "application / x-some-custom-type"), converters: ("text mycustomtype": function (result) (return newresult;)), dataType: "mycustomtype"));

    $. ajax ((

    accepts: (

    mycustomtype: "application / x-some-custom-type"

    converters: (

    "text mycustomtype": function (result) (

    return newresult;

    dataType: "mycustomtype"

    } ) ;

  2. async(default: true)
    Type: boolean.
    By default, all requests are sent asynchronously (that is, after sending a request to the server, the page does not stop its work while waiting for a response). If you need to send requests synchronously, set this option to false. Cross-domain and "jsonp" requests cannot run synchronously. Please note that synchronous requests may block the browser while the request is being executed.
  3. beforeSend (jqXHR, settings)
    Type: function.
    Contains a function that will be called just before the ajax request is sent to the server. Such a function can be useful for modifying a jqXHR object (in earlier versions libraries (up to 1.5), XMLHttpRequest is used instead of jqXHR). For example, you can change / specify the desired headers, etc. Object-jqXHR will be passed to the function as the first argument. The second argument is the request settings.
    beforeSend refers to ajax events. So if the specified function returns false, the ajax request will be canceled. Since jQuery-1.5, beforeSend is called regardless of the request type.
  4. cache(default: true, false for dataType "script" and "jsonp")
    Type: boolean.
    if you want the browser not to cache the request being made, then set this parameter to false. Note that if the parameter is set to false, then the string "_ =" will be added to the URL.
  5. complete (jqXHR, textStatus)
    Type: function.
    A function to execute whenever the AJAX request completes (after success and error have completed). Two parameters are passed to the function: jqXHR (in earlier versions of the library (up to 1.5), XMLHttpRequest is used instead of jqXHR) and the request execution status (string value: "success", "notmodified", "error", "timeout", "abort", or "parsererror").
    Starting with jQuery-1.5, you can pass more than one function to the complete parameter, but an array of functions. All functions will be called in the order in which they are specified in this array.
  6. contents
    Type: object.
    The parameter was introduced in jQuery-1.5. It is given by an object in the format (string: regular expression) and determines how jQuery will parse (parse) the response from the server, depending on its type.
  7. contentType
    Type: boolean or string.
    When a request is sent to the server, the data is transmitted in the format specified in the contentType. The default is' application / x-www-form-urlencoded; charset = UTF-8 'which is fine in most cases. If you specify this parameter explicitly, then it will be passed to the server (even if no data was sent there).
    As of jQuery-1.6, it is possible to pass false to not set the title.
  8. context
    Type: object.
    An object that will become the context after the request is executed (the value passed to the this variable). For example, if you specify a DOM element as the context, then all ajax request handlers will also be executed in the context of this DOM element. In this example keyword this will contain document.body:

    $ .ajax ((url: "test.html", context: document.body)). done (function () ($ (this) .addClass ("done");));

    $. ajax ((

    url: "test.html",

    context: document. body

    )). done (function () (

    $ (this). addClass ("done");

    } ) ;

  9. converters(default: ("* text": window.String, "text html": true, "text json": jQuery.parseJSON, "text xml": jQuery.parseXML))
    Type: object.
    The parameter was introduced in jQuery-1.5. Determines what functions will be used to convert values ​​from one type to another.
  10. crossDomain(default: false for the same domain, true for cross-domain requests)
    Type: boolean.
    The parameter was introduced in jQuery-1.5. If you want to make a cross-domain request (eg JSONP) on the same domain, set the crossDomain setting to true. This allows, for example, to make a server-side redirect to another domain.
  11. data
    Type: object, string, or array.
    Data to be transferred to the server. If the data is not a string, then it is converted to a query string. For GET requests, the data is attached to the URL. The object must be composed of key / value pairs. If the value is an array, then jQuery orders the values ​​based on the traditional setting. By default, for example, (foo: ["bar1", "bar2"]) becomes & foo = bar1 & foo = bar2.
  12. dataFilter (data, type)
    Type: function.
    A function that will carry out preliminary processing of data sent by the server, i.e. it should act as a filter and return a cleaned string. Two parameters are passed to this function: the mentioned data and the parameter value dataType... The function specified in dataFilter should return processed data.
  13. dataType(default: autodetected (xml, json, script, or html))
    Type: string.
    The data type in which to receive a response from the server. If not set, jQuery will try to detect it automatically using the MIME it receives from the server.
  14. error
    Type: function
    A function that will be called if the request to the server fails. It is provided with three parameters: jqXHR (XMLHttpRequest is used up to 1.5), a string describing the error that occurred, and an exception object, if any. Possible values ​​for the second argument are "timeout", "error", "notmodified", and "parsererror" (null may be returned in unexpected cases). As of jQuery-1.5, this parameter can accept either a single function or an array of functions.
    The error event does not occur when dataType is script or JSONP.
  15. global(default: true)
    Type: boolean.
    Responsible for the work of global ajax request events (for example ajaxStart or ajaxStop). If you set this parameter to false, global events for of this request will not be called.
  16. headers
    Type: object.
    The parameter was introduced in jQuery-1.5 Here you can specify additional request headers (header). The values ​​for this setting will be entered prior to calling the beforeSend function, in which final changes to the headers can be made.
  17. ifModified
    Type: boolean.
    When this setting is set to true, the request will be executed with the "successful" status only if the response from the server differs from the previous response. jQuery verifies this by referring to the Last-Modified header. Since jQuery-1.4, in addition to Last-Modified, ‘etag’ is also checked (both are provided by the server and are needed to notify the browser that the requested data from the server has not changed since the previous request).
  18. isLocal
    Type: boolean.
    The parameter was introduced in jQuery-1.5.1 Allows you to set the status of the page source to local (as if it were using the file protocol), even if jQuery recognized it differently. The library decides that the page is launched locally in case of the following protocols: file, * -extension, and widget. It is recommended to set the isLocal parameter value globally - using the $ .ajaxSetup () function, and not in the settings of individual ajax requests.
  19. jsonp
    Type: string or boolean.
    Defines the name of the parameter that is added to the url of the JSONP request (by default, "callback" is used). For example, the setting (jsonp: "onJSONPLoad") is converted to the url part of the string "onJSONPLoad =?" ... Since version 1.5, specifying false in this parameter prevents adding to url additional parameter... In this case, you need to set the jsonpCallback setting value. For example like this: (jsonp: false, jsonpCallback: "callbackName").
  20. jsonpCallback
    Type: string or function.
    Defines the name of the function that will be called when the server responds to a jsonp request. By default, jQuery generates an arbitrary name for this function, which is the preferred option to make the library easier to work with. One of the reasons why you should specify your own function for handling jsonp requests is to improve the caching of GET requests.
    Since jQuery-1.5, you can specify a function in this parameter in order to handle the server response yourself. In this case, the specified function must return the data received from the server (in the specified function, they will be available in the first parameter).
  21. method (default: "GET")
    Type: string.
    The parameter was introduced in jQuery-1.9.0 Allows you to specify the type of request to the server ("POST", "GET", "PUT")
  22. mimeType
    Type: string.
    The parameter appeared in jQuery-1.5.1 In this field, you can specify the data type in which a response is expected from the server instead of XHR
  23. password
    Type: string.
    Password for server authentication, if required.
  24. processData(default true)
    Type: boolean.
    By default, the data sent to the server is converted from an object to a query string (url-format: fName1 = value1 & fName2 = value2 & ...) and sent as "application / x-www-form-urlencoded". If you need to send a DOM document or other data that cannot be converted, set the processData option to false.
  25. scriptCharset
    Type: string.
    Applies only for Ajax GET requests, dataType can be either "jsonp" or "script". If a server on a third-party domain uses an encoding different from yours, you must specify the encoding of the third-party server.
  26. statusCode
    Type: object.
    The parameter was introduced in jQuery-1.5.0 A set of pairs in which the execution codes of the request are mapped to the functions that will be called in this case. For example, for a 404 code (pages do not exist), you can display a message on the screen:

    $ .ajax ((statusCode: (404: function () (alert ("page not found");))));

    $. ajax ((

    statusCode: (

    404: function () (

    alert ("page not found");

    } ) ;


    If the request is successful, then as a parameter, anonymous function will take the same parameters as the functions that handler the successful execution of the request (specified in the parameter success), and in case of an error, they are the same as for the error functions.
  27. success (data, textStatus, jqXHR)
    Type: function, array.
    The function that will be called in case of successful completion of the request to the server. Takes 3 arguments:
    • data (data) sent by the server and pre-processed;
    • a string with the execution status (textStatus);
    • jqXHR object (in versions prior to 1.5, XMLHttpRequest is used instead of jqXHR). Since jQuery 1.5, instead of a single function, this parameter can take an array of functions.
  28. timeout
    Type: number.
    Time to wait for a response from the server in milliseconds. Rewrites global setting the same parameter in $ .ajaxSetup (). If this time is exceeded, the request will end with an error and an error event will occur, which will have the "timeout" status.
    The time is counted from the moment the $ .ajax function is called. It may happen that at this moment several other requests will be launched and the browser will postpone the execution of the current request. In this case, the timeout may complete, although in fact, the request has not even been started yet.
    In jQuery-1.4 and earlier, when the timeout expires, the XMLHttpRequest object will enter an error state and access to its fields may throw an exception. In Firefox 3.0+, script and JSONP requests will not be interrupted when timed out. They will be completed even after this time has expired.
  29. traditional
    Type: boolean.
    Set the value of this parameter to true in order to use the traditional transformation (serialization) parameters.
  30. type(default: "GET")
    Type: string.
    Analogous to the method parameter. The parameter is used in jQuery prior to 1.9.0
  31. url(default: current page address)
    Type: string.
    Specifies the address to which the request will be sent.
  32. username
    Type: string.
    Username for server authentication, if required.
  33. xhr(default: ActiveXObject in IE, the XMLHttpRequest in other browsers)
    Type: function.
    A function that will provide an XMLHttpRequest object. By default, for IE browsers this object is an ActiveXObject, otherwise it is XMLHttpRequest. With this parameter, you can embed your own version of this object.
  34. xhrFields
    Type: object.
    The parameter was introduced in jQuery-1.5.1 A set of (name: value) pairs for changing / adding the values ​​of the corresponding fields of the XMLHttpRequest object. For example, you can set its withCredentials property to true when doing a cross-domain request:

    $ .ajax ((url: a_cross_domain_url, xhrFields: (withCredentials: true)));

    $. ajax ((

    url: a_cross_domain_url,

    xhrFields: (

    withCredentials: true

    } ) ;

As mentioned above, $ .ajax () is the most basic method, and all subsequent methods are just wrappers. There is very little need to call this function, since there are alternatives more high level such as, and. They are easier to understand and use, although $ .ajax () is more flexible.

The simplest use case would be to call $ .ajax () without specifying parameters:

$. ajax ();

Event handlers

The beforeSend, error, dataFilter, success and complete settings allow you to set event handlers that occur at specific points in the execution of each ajax request.

  • beforeSend occurs immediately before the request is sent to the server;
  • error occurs if the request is unsuccessful;
  • dataFilter occurs when data arrives from the server. Allows to process "raw" data sent by the server;
  • success occurs in case of successful completion of the request;
  • complete occurs on any completion of the request.
  • success: function () (

    alert ( "The data was sent successfully.") ;

    } ) ;

    Attention! The above .success (), .error (), and.complete () settings were added in jQuery-1.5 in addition to the default done (), .fail (), and .then () deferred methods to set handlers. however, starting with jQuery-1.8 these three methods will be deprecated.

    DataType parameter

    The $ .ajax () function learns about the type of data sent by the server from the server itself (by means of MIME). In addition, it is possible to personally indicate (clarify) how this data should be interpreted. This is done using the parameter dataType... Possible values ​​for this parameter:

    • "Xml"- the resulting xml document will be available in text form. You can work with him by standard means jQuery (same as with html document).
    • "Html"- the resulting html will be available in text form. If it contains scripts in tags
      The amount of something on the site2.ru server -

      PHP

      Now we need to create a JSON object with data in PHP. Suppose that we have a certain counter stored on the site2.ru server, we will request it from the site1.ru site and get just a number (the amount of something). Note that we have to create a JSONP object instead of a regular JSON object.

      // Create an array with the data that we want to send json with the response $ data = array ("counter" => 5,); // Translate the array to JSON $ json_data = json_encode ($ data); // Set the encoding and content type header ("Content-type: application / json; charset = utf-8"); // JSONP - make a JSONP object echo $ _GET ["callback"]. "(". $ json_data. ");";

      Save the file as counter.php and upload it to the site2.ru server

      JAVASCRIPT

      Now we need to call $ .ajax in jQuery as described below:

      $ (document) .ready (function () ($ .ajax ((type: "GET", url: "http://site2.ru/counter.php?callback=?", dataType: "jsonp", success: function (data) ($ (". text .counter"). html (data.counter);)));));

      If you don't specify a callback function, but just write callback =? - then the name of the jQuery function is substituted automatically, but you can also explicitly specify the name of the function, for example callback = parseFunction.

      Now run the HTML file on site1.ru. You should receive a response from the server with json data. You can also use this cross-browser ajax for $ .getJSON, $ .ajax, $ .post and $ .get.

      P.S. Do not forget to replace site2.ru in the example with the name of your remote server to which you are making a request.

      If you have any questions or additions, write in the comments below.