JQuery AJAX cross domain
Вот две страницы: 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")
; Если он находится на разных серверах, то есть testerver.php на веб-сервере и test.php на localhost, его не работает и alert("Error")
выполняется. Даже если URL-адрес внутри ajax изменен на http://domain.com/path/to/file/testserver.php
Ответы
Ответ 1
Используйте 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 (да, значение is?, jQuery заменяет его собственным методом обратного вызова).
Ответ 2
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.
Ответ 3
Вы можете управлять этим через HTTP-заголовок, добавив Access-Control-Allow-Origin. Установка его на * будет принимать междоменные запросы AJAX из любого домена.
Использование PHP действительно просто, просто добавьте следующую строку в script, к которой вы хотите получить доступ из своего домена:
header("Access-Control-Allow-Origin: *");
Не забудьте включить модуль mod_headers в httpd.conf.
Ответ 4
Вам нужно взглянуть на Одинаковая политика происхождения:
При вычислении одна и та же политика происхождения является важной концепцией безопасности для количество программ на стороне браузера языки, такие как JavaScript. политика разрешает выполнение скриптов страницы, происходящие с того же сайта для доступа к другим методам и свойства без конкретных ограничений, но препятствует доступу к большинство методов и свойств в страниц на разных сайтах.
Чтобы вы могли получать данные, это должно быть:
Тот же протокол и хост
Вам нужно реализовать JSONP, чтобы обойти это.
Ответ 5
Мне пришлось загрузить веб-страницу с локального диска "file:///C:/test/htmlpage.html", вызвать url "http://localhost/getxml.php" и сделать это в браузерах IE8 + и Firefox12 + используйте jQuery v1.7.2 lib, чтобы свести к минимуму шаблонный код. После прочтения десятки статей, наконец, понял это. Вот мое резюме.
- сервер script (.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);
}
});
Ответ 6
Верно, что политика одного и того же происхождения предотвращает выполнение запросов JavaScript по всем доменам, но спецификация CORS позволяет использовать только тот вид доступа к API, который вам нужен, и поддерживается текущей группой основных браузеров.
Посмотрите, как включить совместное использование ресурсов между клиентом и сервером:
http://enable-cors.org/
"Совместное использование ресурсов (CORS) - это спецификация, которая позволяет по-настоящему открывать доступ через границы домена. Если вы обслуживаете общедоступный контент, рассмотрите возможность использования CORS, чтобы открыть его для универсального доступа к JavaScript/браузерам".
Ответ 7
Это возможно, но вам нужно использовать JSONP, а не JSON. Ссылка Стефана указала вам в правильном направлении. Страница jQuery AJAX содержит дополнительную информацию о JSONP.
У Remy Sharp есть подробный пример с использованием PHP.
Ответ 8
Я использую сервер 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/
Наконец, передайте прокси-url на ваш script.
Ответ 9
Защита браузера предотвращает создание ajax-звонка со страницы, размещенной в одном домене, на страницу, размещенную в другом домене; это называется " политика одного и того же происхождения".
Ответ 10
Существует несколько примеров использования JSONP, которые включают обработку ошибок.
Однако обратите внимание, что при использовании JSONP событие ошибки не запускается! Смотрите: http://api.jquery.com/jQuery.ajax/ или jQuery ajax-запрос с использованием jsonp-ошибки
Ответ 11
Из документов Jquery (ссылка):
-
Из-за ограничений безопасности браузера большинство запросов "Ajax" подчиняются одной и той же политике происхождения; запрос не может успешно извлекать данные из другого домена, субдомена или протокола.
-
Script, а запросы JSONP не подпадают под одни и те же ограничения политики происхождения.
Поэтому я бы сказал, что вам нужно использовать jsonp для запроса. Но не пробовал это сам.
Ответ 12
Я знаю 3 способа решить вашу проблему:
-
Сначала, если у вас есть доступ к обоим доменам, вы можете разрешить доступ ко всем другим доменам, используя:
header("Access-Control-Allow-Origin: *");
или просто домен, добавив следующий код в файл.htaccess:
<FilesMatch "\.(ttf|otf|eot|woff)$"> <IfModule mod_headers.c> SetEnvIf Origin "http(s)?://(www\.)?(google.com|staging.google.com|development.google.com|otherdomain.net|dev02.otherdomain.net)$" AccessControlAllowOrigin=$0 Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin </IfModule> </FilesMatch>
-
вы можете получить запрос ajax в php файл на своем сервере и обработать запрос в другом домене, используя этот php файл.
- вы можете использовать jsonp, потому что ему не требуется разрешение. для этого вы можете прочитать ответ нашего друга @BGerrissen.
Ответ 13
Для Microsoft Azure это немного отличается.
Azure имеет специальную настройку CORS, которая должна быть установлена. Это по сути то же самое, что и за кулисами, но просто установка заголовка joshuarh упоминаний не будет работать. Документацию Azure для включения кросс-домена можно найти здесь:
https://docs.microsoft.com/en-us/azure/app-service-api/app-service-api-cors-consume-javascript
Я поработал с этим в течение нескольких часов, прежде чем осознать, что моя хостинговая платформа имеет эту специальную настройку.
Ответ 14
он работает, все, что вам нужно:
PHP:
header('Access-Control-Allow-Origin: http://www.example.com');
header("Access-Control-Allow-Credentials: true");
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
JS (jQuery ajax):
var getWBody = $.ajax({ cache: false,
url: URL,
dataType : 'json',
type: 'GET',
xhrFields: { withCredentials: true }
});
Ответ 15
Для запросов AJAX с перекрестным контуром используйте следующий плагин jQuery.
https://github.com/jinujd/jQuery-Async-Form
Он работает асинхронно, без перезагрузки.
Это не AJAX, но в большинстве случаев он выполняет задачу