JQuery AJAX междоменный - PullRequest
       27

JQuery AJAX междоменный

460 голосов
/ 17 августа 2010

Вот две страницы, test.php и testserver.php.

test.php

<script src="scripts/jq.js" type="text/javascript"></script>
<script>
    $(function() {
        $.ajax({url:"testserver.php",
            success:function() {
                alert("Success");
            },
            error:function() {
                alert("Error");
            },
            dataType:"json",
            type:"get"
        }
    )})
</script>

testserver.php

<?php
$arr = array("element1",
             "element2",
             array("element31","element32"));
$arr['name'] = "response";
echo json_encode($arr);
?>

Теперь моя проблема: когда оба эти файла находятся на одном и том же сервере (локальном или веб-сервере), он работает и вызывается alert("Success"); Если он находится на разных серверах, то есть testserver.php на веб-сервере и test.php на localhost, он не работает, и alert("Error") выполняется. Даже если URL внутри ajax изменен на http://domain.com/path/to/file/testserver.php

Ответы [ 14 ]

406 голосов
/ 17 августа 2010

Использование JSONP .

jQuery:

$.ajax({
     url:"testserver.php",
     dataType: 'jsonp', // Notice! JSONP <-- P (lowercase)
     success:function(json){
         // do stuff with json (in this case an array)
         alert("Success");
     },
     error:function(){
         alert("Error");
     }      
});

PHP:

<?php
$arr = array("element1","element2",array("element31","element32"));
$arr['name'] = "response";
echo $_GET['callback']."(".json_encode($arr).");";
?>

Эхо может быть неправильным, это было давнотак как я использовал php.В любом случае вам нужно вывести callbackName('jsonString') заметить кавычки.jQuery передаст свое собственное имя обратного вызова, поэтому вам нужно получить его из параметров GET.

И, как написал Стефан Кендалл, $. getJSON () - это сокращенный метод, но тогда вынеобходимо добавить 'callback=?' к URL в качестве параметра GET (да, значение равно?, jQuery заменяет его собственным сгенерированным методом обратного вызова).

199 голосов
/ 02 марта 2012

JSONP - хороший вариант, но есть более простой способ.Вы можете просто установить заголовок Access-Control-Allow-Origin на своем сервере.При установке значения * междоменные запросы AJAX будут приниматься из любого домена.(https://developer.mozilla.org/en/http_access_control)

Метод для этого, конечно, будет отличаться от языка к языку. Вот в Rails:

class HelloController < ApplicationController
  def say_hello
    headers['Access-Control-Allow-Origin'] = "*"
    render text: "hello!"
  end
end

В этом примере действие say_hello будетпринимать запросы AJAX от любого домена и возвращать ответ «привет!».

Вот пример заголовков, которые он может вернуть:

HTTP/1.1 200 OK 
Access-Control-Allow-Origin: *
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Type: text/html; charset=utf-8
X-Ua-Compatible: IE=Edge
Etag: "c4ca4238a0b923820dcc509a6f75849b"
X-Runtime: 0.913606
Content-Length: 6
Server: WEBrick/1.3.1 (Ruby/1.9.2/2011-07-09)
Date: Thu, 01 Mar 2012 20:44:28 GMT
Connection: Keep-Alive

Как легко, он имеетнекоторые ограничения браузера. См. http://caniuse.com/#feat=cors.

29 голосов
/ 29 ноября 2014

Вы можете контролировать это через HTTP-заголовок, добавив Access-Control-Allow-Origin .Установка этого параметра на * будет принимать междоменные запросы AJAX из любого домена.

Использование PHP это действительно просто, просто добавьте следующую строку в скрипт, который вы хотите иметь доступ извне из вашего домена.домен:

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

Не забудьте включить модуль mod_headers в httpd.conf.

19 голосов
/ 17 августа 2010

Вам нужно взглянуть на Одинаковая политика происхождения :

В вычислениях, та же политика происхождения является важной концепцией безопасности для количество программ на стороне браузера языки, такие как JavaScript. политика разрешает скрипты, работающие на страницы с того же сайта чтобы получить доступ к методам друг друга и свойства без конкретного ограничения, но препятствует доступу к большинство методов и свойств по всему страницы на разных сайтах.

Чтобы вы могли получать данные, оно должно быть:

Тот же протокол и хост

Вам нужно реализовать JSONP , чтобы обойти это.

16 голосов
/ 16 мая 2012

Мне пришлось загрузить веб-страницу с локального диска "file: /// C: /test/htmlpage.html", вызвать "http://localhost/getxml.php" url" и сделать это в браузерах IE8 + и Firefox12 +, использовать библиотеку jQuery v1.7.2 для свести к минимуму стандартный код. После прочтения десятков статей, наконец, понял это. Вот мое резюме.

  • серверный скрипт (.php, .jsp, ...) должен возвращать HTTP-заголовок ответа Access-Control-Allow-Origin: *
  • перед использованием jQuery ajax установите этот флаг в javascript: jQuery.support.cors = true;
  • вы можете установить флаг один или каждый раз перед использованием jQuery ajax-функции
  • теперь я могу читать .xml документ в IE и Firefox. Другие браузеры я не тестировал.
  • Ответный документ может быть простым / текстовым, XML, JSON или любым другим

Вот пример вызова jQuery ajax с некоторыми sysouts отладки.

jQuery.support.cors = true;
$.ajax({
    url: "http://localhost/getxml.php",
    data: { "id":"doc1", "rows":"100" },
    type: "GET",
    timeout: 30000,
    dataType: "text", // "xml", "json"
    success: function(data) {
        // show text reply as-is (debug)
        alert(data);

        // show xml field values (debug)
        //alert( $(data).find("title").text() );

        // loop JSON array (debug)
        //var str="";
        //$.each(data.items, function(i,item) {
        //  str += item.title + "\n";
        //});
        //alert(str);
    },
    error: function(jqXHR, textStatus, ex) {
        alert(textStatus + "," + ex + "," + jqXHR.responseText);
    }
});
10 голосов
/ 29 августа 2013

Это правда, что политика одного и того же происхождения не позволяет JavaScript выполнять запросы между доменами, но спецификация CORS разрешает только тот тип доступа к API, который вы ищете, и поддерживается текущей партией основных браузеров.

Посмотрите, как включить совместное использование ресурсов между источниками для клиента и сервера:

http://enable -cors.org /

"Обмен ресурсами между источниками (CORS) - это спецификация, которая обеспечивает действительно открытый доступ через границы домена. Если вы предоставляете общедоступный контент, рассмотрите возможность использования CORS, чтобы открыть его для универсального доступа JavaScript / браузера. "

9 голосов
/ 02 апреля 2012

Я использую сервер Apache, поэтому я использовал модуль mod_proxy.Включите модули:

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so

Затем добавьте:

ProxyPass /your-proxy-url/ http://service-url:serviceport/

Наконец, передайте proxy-url в ваш скрипт.

9 голосов
/ 17 августа 2010

Это возможно, но вам нужно использовать JSONP, а не JSON. Ссылка Стефана указала вам в правильном направлении. Страница jQuery AJAX содержит дополнительную информацию о JSONP.

У Реми Шарпа есть подробный пример с использованием PHP .

8 голосов
/ 17 августа 2010

Безопасность браузера предотвращает вызов ajax со страницы, размещенной в одном домене, на страницу, размещенную в другом домене; это называется " политика того же происхождения ".

5 голосов
/ 10 мая 2013

Существует несколько примеров использования JSONP, которые включают обработку ошибок.

Однако обратите внимание, что событие error не вызывается при использовании JSONP!См .: http://api.jquery.com/jQuery.ajax/ или jQuery ajax-запрос с использованием ошибки jsonp

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...