API Википедии + запросы с кросс-началом

Я пытаюсь получить доступ к wikipedia, используя javascript + CORS

Насколько я знаю, wikipedia должна поддерживать CORS: http://www.mediawiki.org/wiki/API:Cross-site_requests

Я попробовал следующий script: создать XMLHttpRequest + credential/XDomainRequest, добавить некоторые Http-заголовки ( "Access-Control-Allow-Credentials",...) и отправить запрос.

http://jsfiddle.net/lindenb/Vr7RS/

var WikipediaCORS=
    {
    setMessage:function(msg)
        {
        var span=document.getElementById("id1");
        span.appendChild(document.createTextNode(msg));
        },
    // Create the XHR object.
    createCORSRequest:function(url)
        {
        var xhr = new XMLHttpRequest();


        if ("withCredentials" in xhr)
            {
            xhr.open("GET", url, true);
            }
        else if (typeof XDomainRequest != "undefined")
            {
            xhr = new XDomainRequest();
            xhr.open(method, url);
            }
        else
            {
            return null;
            }
        xhr.setRequestHeader("Access-Control-Allow-Credentials", "true");
        xhr.setRequestHeader("Access-Control-Allow-Origin","*");
        return xhr;
        },
    init:function()
        {
        var _this=this;
        var url = 'http://en.wikipedia.org/w/api.php?action=opensearch&search=Javascript&format=json';
        var xhr = this.createCORSRequest(url);
        if (!xhr)
            {
                this.setMessage('CORS not supported');
                return;
            }

        xhr.onload = function()
            {
                _this.setMessage(xhr.responseText);
            };
        xhr.onerror = function()
            {
                _this.setMessage('Woops, there was an error making the request.');
            };
        xhr.send();
        }
    };

Но мой script не работает (вызывается "xhr.onerror" ). Как я могу это исправить?

Спасибо.

Ответ 1

Заголовки CORS отправляются для доступа к запросу script для доступа к содержимому.

Википедия отправляет CORS, а не ВЫ.

На странице, которую вы указали:

API MediaWiki также требует, чтобы источник был поставлен как параметр запроса, соответствующий названию "происхождение", который сопоставляется против заголовка Origin, требуемого по протоколу CORS. Обратите внимание, что этот заголовок должен быть включен в любой запрос перед полетом, и поэтому быть включенным в часть строки запроса URI запроса даже для POST-запросы.

Если проверка происхождения CORS проходит, MediaWiki будет включать Access-Control-Allow-Credentials: истинный заголовок в ответе, поэтому файлы cookie аутентификации могут быть отправлены.

Это означает, что вам нужно отправить заголовок Origin, чтобы сообщить wikipedia, откуда вы пришли. Википедия управляет доступом, а не вы.

Отправить этот исходный заголовок:

xhr.setRequestHeader("Origin", "http://www.yourpage.com");
Заголовки

Access-Control-Allow-* представляют заголовки ответ, а не запрос.

Википедии дополнительно требуется тип содержимого json:

xhr.setRequestHeader("Content-Type", "application/json; charset=UTF-8");

Ответ 2

У меня была та же проблема, когда я работал над проектом freeCodeCamp, и решение было настолько простым, что заставило меня смеяться, поскольку я часами искал его. В ваш jQuery URL включите параметр ниже.

&origin=*

рабочий Codepen

$.getJSON(
  'https://en.wikipedia.org/w/api.php?action=query&format=json&gsrlimit=15&generator=search' +
  '&origin=*' + // <-- this is the magic ingredient!
  '&gsrsearch='q, function(data){ /* ... */ }
);

Ответ 3

На сегодняшний день Wikipedia поддерживает запросы CORS, используя обычные запросы ajax (нет необходимости в обработке JSONP/обратного вызова). Это можно сделать, установив начало в вызове API.

Для аутентифицированных запросов это должно совпадать с одним из "истоков" в заголовке Origin точно (вам нужно установить это с помощью свойства beforeSend при вызове ajax).
Для неавторизованных запросов вы можете просто установить его как звездочку (*), и она работает при использовании простого $.getJSON из вашего домена. Пример вызова api:
https://en.wikipedia.org//w/api.php?action=opensearch&format=json&origin=*&search=stack&limit=10
Подробнее в тестовой среде MediaWiki API: MediaWiki API песочница

Ответ 4

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

$.ajax( {
    url: "https://en.wikipedia.org/w/api.php",
    jsonp: "callback", 
    dataType: 'jsonp', 
    data: { 
        action: "query", 
        list: "search", 
        srsearch: "javascript", 
        format: "json" 
    },
    xhrFields: { withCredentials: true },
    success: function(response) { ... }
}