jQuery.ajax() для JSONP возвращает 200, но ошибка синтаксического анализа запускает обратный вызов ошибки вместо обратного вызова успеха

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

Я хочу получить JSON файл с веб-сервера. Файл JSON был проверен JSONLint, поэтому синтаксис проверен как "ОК". Данные JSON извлекаются из URL-адреса, подобного этому: www.examplewebsite.com/data.json

Мой код jQuery Ajax:

$.ajax({

    url:url",
    dataType:"jsonp",
    contentType: "application/json",
    type:"get",
    success:function(){
        console.log("OK");
    },
    error:function(data,status,error){
        console.log(data " "status+" "+error);
    }
});

Это ошибка:

: parsererror Ошибка: jQuery222030055767520832166_1465026956736 не был вызван

Что я сделал до сих пор:

  • Добавлена функция обратного вызова (jsonpCallback: fname) (я действительно хочу знать, что если нам нужно добавить функцию обратного вызова для доступа к стороне сервера JSON?), Функция fname работает (alert("OK");), но я все равно получаю ошибки. Одно из сообщений об ошибках было "undefined was not called"
  • Добавлена опция jsonp: false
  • Изменен dataType: jsonp to json, но получил ошибку Access-Control-Allow-Origin
  • Дважды проверьте, действительно ли результирующий JSON

Update1

Мой json-контент (используемый для тестирования):

[{
  "id": 1,
  "first_name": "Sara"
}, {
  "id": 2,
  "first_name": "Lois"
}, {
  "id": 3,
  "first_name": "Annie"
}, {
  "id": 4,
  "first_name": "Gregory"
}, {
  "id": 5,
  "first_name": "Fred"
}, {
  "id": 6,
  "first_name": "Antonio"
}, {
  "id": 7,
  "first_name": "Denise"
}, {
  "id": 8,
  "first_name": "Susan"
}, {
  "id": 9,
  "first_name": "Jeffrey"
}, {
  "id": 10,
  "first_name": "Jean"
}]

UPDATE2 Согласно объяснениям @Michael, я обновил заголовки и код ajax, dataType: "json", но я получил ошибку Access-Control-Allow-Origin. Мои результаты проверки заголовков для файла json:

HTTP/1.1 200 OK => 
Date => Sun, 05 Jun 2016 00:21:59 GMT
Server => Apache
Last-Modified => Sat, 04 Jun 2016 22:27:58 GMT
Accept-Ranges => bytes
Content-Length => 440
Access-Control-Allow-Origin => *
Access-Control-Allow-Headers => origin, x-requested-with, content-type
Access-Control-Allow-Methods => PUT, GET, POST, DELETE, OPTIONS
Keep-Alive => timeout=10, max=200
Content-Type => application/json
Connection => close

Есть идеи? PS: Кроме того, я попытался написать другой метод (IfModule), который все еще получил проблему.

+2
04 июн. '16 в 8:17
источник поделиться
1 ответ

Данные, которые вы пытаетесь получить, это JSON, а не JSONP. Запрос JSON на другой домен через Ajax приведет к ошибке Access Control Allow Origin, которая, как вы нашли. Ajax позволит получить JSONP из другого домена, но на самом деле контент должен быть JSONP, или вы получите ошибку синтаксического анализа, как вы нашли.

Так что ты можешь сделать? Если вы управляете сервером, с которого запрашиваются данные JSON, вы можете обрабатывать запросы из своего домена с помощью заголовков ответов. Вам нужно только установить эти заголовки:

  • Access-Control-Allow-Origin: ваш сервер
  • Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS
  • Access-Control-Max-Age: 3600
  • Access-Control-Allow-Headers

После этого вы можете просто выполнить вызов JSON (не JSONP) Ajax, и вы будете установлены.

Если по какой-то причине вы не можете полагаться на CORS, и вы управляете удаленным сервером, просто возвращайте данные как JSONP вместо JSON.

Однако, если вы не контролируете удаленный сервер или не можете использовать CORS по какой-то причине, все становится странно довольно быстро. Ответ на вопрос: Как отправить запрос POST для междоменного доступа через JavaScript? дает хорошее объяснение того, как сделать эту работу с iframes и window.postMessage. Конечно, этот пример для POST, но вся информация сохраняется, если вы просто пытаетесь ПОЛУЧИТЬ с удаленного сервера.

В этом случае очень сложно дать точный ответ, потому что нет никакой информации о том, управляете ли вы удаленным сервером, и какой язык/технология стека использует ваш собственный сервер. Существует превосходное покрытие различных решений в статье 4 jQuery Cross-Domain AJAX Request, и один из них может решить вашу проблему (обязательно обратите внимание на недостатки каждого из них, прежде чем принимать решение об этом).

Если вы все еще находитесь в тупике на данный момент, вам следует подумать о том, чтобы использовать свой собственный сервер в качестве прокси-сервера, так что вызов Ajax может быть сделан на ваш сервер, а затем ваш сервер может сделать междоменный вызов удаленному серверу для извлечения данных. Это приведет к более длительному времени отклика, но даст вам именно то, что вам нужно, с полным контролем над каждым аспектом процесса. Обычно это делается на нескольких строках кода, но это нужно делать на сервере.

Рассмотрим пример прокси-сервера Ruby on Rails:

def json_proxy
  Net::HTTP.start("www.examplewebsite.com") do |http|
    render json: http.get("/data.json")
  end
end

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

Для получения дополнительной информации о CORS см. Спецификацию совместного использования ресурсов W3C Cross-Origin для получения подробной информации о том, как работает CORS. Вы также должны взглянуть на прекрасное покрытие в html5rocks.com. Используя CORS, так как это охватывает довольно много основ того, как работает CORS и что вы можете сделать в среде CORS.

+2
04 июн. '16 в 19:36
источник

Посмотрите другие вопросы по меткам или Задайте вопрос