JQuery.getJSON - проблема с доступом-контролем-разрешением-источником
Я запускаю функцию jQuery $.getJSON()
, чтобы вернуть короткий набор данных JSON.
У меня есть данные JSON, сидящие на URL-адресе, например example.com
.
Я этого не понимал, но когда я обращался к тому же URL-адресу, данные JSON не могли быть загружены. Я прошел через консоль и обнаружил, что XMLHttpRequest
не удалось загрузить из-за Access-Control-Allow-Origin
.
Теперь, я прочитал, много сайтов, которые только что сказали $.getJSON()
, и это будет работать, но, очевидно, это не сработало. Есть ли что-то, что я должен изменить в заголовках или в функции?
Помощь приветствуется.
Ответы
Ответ 1
Это просто, используйте функцию $.getJSON()
и в вашем URL-адресе просто включите
= обратный вызов?
в качестве параметра. Это преобразует вызов в JSONP, который необходим для совершения междоменных вызовов. Дополнительная информация: http://api.jquery.com/jQuery.getJSON/
Ответ 2
Возможно, вы захотите использовать JSON-P (см. ниже). Сначала краткое объяснение.
Заголовок, о котором вы упоминали, относится к стандарту Cross Origin Resource Sharing. Остерегайтесь того, что некоторые пользователи браузеров фактически не поддерживают , а в других браузерах (Microsoft, вздох) требуется использование специального объекта (XDomainRequest
), а не стандартный XMLHttpRequest
, который использует jQuery. Это также требует, чтобы вы изменили ресурсы на стороне сервера, чтобы явно разрешить другое происхождение (www.xxxx.com
).
Чтобы получить данные JSON, которые вы запрашиваете, у вас есть три варианта:
-
Если возможно, вы можете быть максимально совместимы, исправляя местоположение загружаемых файлов, чтобы они имели то же происхождение, что и документ, в который вы его загружаете. (Я предполагаю, что вы должны загружать их через Ajax, поэтому появляется проблема Same Origin Policy.
-
Используйте JSON-P, который не подпадает под действие SOP. jQuery имеет встроенную поддержку для этого в своем вызове ajax
(просто установите dataType
в "jsonp", и jQuery выполнит всю работу на стороне клиента). Это требует изменений на стороне сервера, но не очень больших; в основном все, что у вас есть, что генерирование ответа JSON просто ищет параметр строки запроса, называемый "обратный вызов", и переносит JSON в код JavaScript, который будет вызывать эту функцию. Например, если ваш текущий ответ JSON:
{"weather": "Dreary start but soon brightening into a fine summer day."}
Ваш script будет искать параметр строки запроса "обратный вызов" (скажем, что значение параметра - "jsop123" ) и заверяет, что JSON в синтаксисе для вызова функции JavaScript:
jsonp123({"weather": "Dreary start but soon brightening into a fine summer day."});
Что это. JSON-P очень широко совместим (потому что он работает с помощью тегов JavaScript script
). JSON-P предназначен только для GET
, но не POST
(опять же потому, что он работает с помощью тегов script
).
-
Используйте CORS (механизм, связанный с указанным вами заголовком). Подробности в спецификация, указанная выше, но в основном:
а. Браузер отправит вашему серверу сообщение "preflight", используя OPTIONS
HTTP-глагол (метод). Он будет содержать различные заголовки, которые он отправит с помощью GET
или POST
, а также заголовки "Origin", "Access-Control-Request-Method" (например, GET
или POST
) и "Access-Control-Request-Headers" (заголовки, которые он хочет отправить).
В. Ваш PHP решает на основе этой информации, является ли запрос в порядке, и если так отвечает "Access-Control-Allow-Origin", "Access-Control-Allow-Methods" и "Access-Control-Allow-Headers", заголовки со значениями, которые это позволит. Вы не отправляете ни одного тела (страницы) с этим ответом.
С. Браузер рассмотрит ваш ответ и посмотрит, разрешено ли ему отправлять фактические GET
или POST
. Если это так, он отправит этот запрос снова с заголовками "Origin" и различными заголовками "Access-Control-Request-xyz".
Д. Ваш PHP снова проверяет эти заголовки, чтобы убедиться, что они все еще в порядке, и если так отвечает на запрос.
В псевдо -коде (я не сделал много PHP, поэтому я не пытаюсь использовать синтаксис PHP здесь):
// Find out what the request is asking for
corsOrigin = get_request_header("Origin")
corsMethod = get_request_header("Access-Control-Request-Method")
corsHeaders = get_request_header("Access-Control-Request-Headers")
if corsOrigin is null or "null" {
// Requests from a `file://` path seem to come through without an
// origin or with "null" (literally) as the origin.
// In my case, for testing, I wanted to allow those and so I output
// "*", but you may want to go another way.
corsOrigin = "*"
}
// Decide whether to accept that request with those headers
// If so:
// Respond with headers saying what allowed (here we're just echoing what they
// asked for, except we may be using "*" [all] instead of the actual origin for
// the "Access-Control-Allow-Origin" one)
set_response_header("Access-Control-Allow-Origin", corsOrigin)
set_response_header("Access-Control-Allow-Methods", corsMethod)
set_response_header("Access-Control-Allow-Headers", corsHeaders)
if the HTTP request method is "OPTIONS" {
// Done, no body in response to OPTIONS
stop
}
// Process the GET or POST here; output the body of the response
Снова подчеркивая, что это псевдокод.