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"}]
Вы знаете, почему я получаю эту ошибку?
Ответы
Ответ 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!