Подтвердить что ты не робот

JQuery.getJSON - проблема с доступом-контролем-разрешением-источником

Я запускаю функцию jQuery $.getJSON(), чтобы вернуть короткий набор данных JSON.

У меня есть данные JSON, сидящие на URL-адресе, например example.com. Я этого не понимал, но когда я обращался к тому же URL-адресу, данные JSON не могли быть загружены. Я прошел через консоль и обнаружил, что XMLHttpRequest не удалось загрузить из-за Access-Control-Allow-Origin.

Теперь, я прочитал, много сайтов, которые только что сказали $.getJSON(), и это будет работать, но, очевидно, это не сработало. Есть ли что-то, что я должен изменить в заголовках или в функции?

Помощь приветствуется.

4b9b3361

Ответ 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
    

    Снова подчеркивая, что это псевдокод.