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

XMLHttpRequest не может загрузить URL-адрес с помощью jQuery

Я пытаюсь получить некоторые json-данные с веб-сайта "remote". Затем я запускаю свою веб-службу на 99000-порте, я запускаю свой сайт на 99001-порту (http://localhost: 99001/index.html).

Получаю следующее сообщение:

    XMLHttpRequest cannot load http://localhost:99000/Services.svc/ReturnPersons. Origin http://localhost:99001 is not allowed by Access-Control-Allow-Origin.

Даже если я запустил свою веб-страницу в виде HTML файла, я получаю следующее:

    XMLHttpRequest cannot load http://localhost:99000/Services.svc/ReturnPersons.Origin null is not allowed by Access-Control-Allow-Origin.

Веб-служба возвращает данные. Я пытаюсь поймать элементы данных следующим образом:

var url = "http://localhost:99000/Services.svc/ReturnPersons";
$.getJSON(url, function (data) {
success: readData(data)
});
function readData(data) {
    alert(data[0].FirstName);
}

И я пытаюсь получить эту структуру:

[{"FirstName":"Foo","LastName":"Bar"},{"Hello":"Foo","LastName":"World"}]

Вы знаете, почему я получаю эту ошибку?

4b9b3361

Ответ 1

Вы не можете использовать crosshain XMLHttpRequest, единственной "опцией" будет метод JSONP, который сводится к следующему:

Чтобы начать запрос: добавьте новый тег <script> с удаленным URL-адресом, а затем убедитесь, что удаленный url возвращает действительный файл javascript, который вызывает вашу функцию обратного вызова. Некоторые службы поддерживают это (и позволяют вам называть ваш обратный вызов в параметрах GET).

Другим простым способом было бы создать "прокси" на вашем локальном сервере, который получит удаленный запрос, а затем просто "переадресует" его обратно в ваш javascript.

редактирование/добавление:

Я вижу, что jQuery имеет встроенную поддержку JSONP, проверяя, содержит ли URL-адрес "callback =?" (где jQuery заменит? фактическим методом обратного вызова). Но вы все равно должны обработать это на удаленном сервере, чтобы создать правильный ответ.

Ответ 2

В новом jQuery 1.5 вы можете использовать:

$.ajax({
    type: "GET",
    url: "http://localhost:99000/Services.svc/ReturnPersons",
    dataType: "jsonp",
    success: readData(data),
    error: function (xhr, ajaxOptions, thrownError) {
      alert(xhr.status);
      alert(thrownError);
    }
})

Ответ 3

Скрипт с 3 рабочими решениями в действии.

Для внешнего JSON:

myurl = 'http://wikidata.org/w/api.php?action=wbgetentities&sites=frwiki&titles=France&languages=zh-hans|zh-hant|fr&props=sitelinks|labels|aliases|descriptions&format=json'

Решение 1: $.ajax() + jsonp:

$.ajax({
  dataType: "jsonp",
  url: myurl ,
  }).done(function ( data ) {
  // do my stuff
});

Решение 2: $.ajax() + json + & calback =?:

$.ajax({
  dataType: "json",
  url: myurl + '&callback=?',
  }).done(function ( data ) {
  // do my stuff
});

Решение 3: $.getJSON() + calback =?:

$.getJSON( myurl + '&callback=?', function(data) {
  // do my stuff
});

Документация: http://api.jquery.com/jQuery.ajax/, http://api.jquery.com/jQuery.getJSON/

Ответ 4

Обнаружено возможное обходное решение, о котором я не думаю, было упомянуто.

Вот хорошее описание проблемы: http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api

В принципе, до тех пор, пока вы используете формы с формами/URL-кодированными/текстовыми текстами, вы в порядке.

$.ajax({
    type: "POST",
    headers: {
        'Accept': 'application/json',
        'Content-Type': 'text/plain'
    },
    dataType: "json",
    url: "http://localhost/endpoint",
    data: JSON.stringify({'DataToPost': 123}),
    success: function (data) {
        alert(JSON.stringify(data));
    }
});     

Я использую его с ASP.NET WebAPI2. Итак, на другом конце:

public static void RegisterWebApi(HttpConfiguration config)
{
    config.MapHttpAttributeRoutes();

    config.Formatters.Clear();
    config.Formatters.Add(new JsonMediaTypeFormatter());

    config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/plain"));
}

Таким образом, форматирование Json используется при анализе типа текстового содержимого.

И не забывайте в Web.config:

<system.webServer>
<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />
    <add name="Access-Control-Allow-Methods" value="GET, POST" />
  </customHeaders>
</httpProtocol>    

Надеюсь, что это поможет.

Ответ 5

Я использую WebAPI 3 и столкнулся с той же проблемой. Проблема решена, поскольку @Rytis добавил свое решение. И я думаю, что в WebAPI 3 нам не нужно определять метод RegisterWebApi.

Мое изменение было только в файле web.config и работает.

<httpProtocol>
 <customHeaders>
 <add name="Access-Control-Allow-Origin" value="*" />
 <add name="Access-Control-Allow-Methods" value="GET, POST" />
</customHeaders>
</httpProtocol> 

Спасибо за решение @Rytis!