维基百科API +跨域请求

时间:2014-05-30 10:08:31

标签: javascript cors wikipedia-api

我正在尝试使用javascript + CORS

访问维基百科

据我所知,维基百科应支持CORS:http://www.mediawiki.org/wiki/API:Cross-site_requests

我尝试了以下脚本:创建XMLHttpRequest +凭证/ XDomainRequest,添加一些Http-Headers(“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();
        }
    };

但是我的脚本失败了('xhr.onerror'被调用)。我该如何解决?

感谢。

5 个答案:

答案 0 :(得分:73)

我在使用freeCodeCamp项目时遇到了同样的问题,解决方案非常简单,这让我大笑,因为我花了几个小时搜索它。在您的jQuery URL中包含以下参数。

<meta name="viewport" content="width=device-width, initial-scale=1.0">

working Codepen

&origin=*

答案 1 :(得分:15)

截至今天,Wikipedia通过使用正常的ajax请求(不需要JSONP /回调操作)来支持CORS请求。 这可以通过在API调用中设置原点来完成。

对于经过身份验证的请求,这必须与&#34; origin&#34;之一匹配。完全在Origin标题中(你需要在进行ajax调用时使用beforeSend属性设置它) 对于未经身份验证的请求,您只需将其设置为星号(*),并且在使用域中的简单$ .getJSON时它可以正常工作。 示例api调用:
https://en.wikipedia.org//w/api.php?action=opensearch&format=json&origin=*&search=stack&limit=10
更多内容来自MediaWiki API沙箱:MediaWiki API sandbox

答案 2 :(得分:10)

发送CORS标头以允许请求脚本访问内容。

维基百科正在发送CORS,而不是你。

从您关联的页面:

  

MediaWiki API还要求将原点作为a提供   请求参数,适当命名为&#34; origin&#34;,匹配   反对CORS协议的 Origin标题。注意   此标头必须包含在任何转机前请求中,因此也应如此   被包含在请求URI的查询字符串部分中,即使对于   POST请求。

     

如果CORS原始检查通过, MediaWiki将包括   Access-Control-Allow-Credentials:响应中的true标头,所以   可以发送身份验证cookie。

这意味着你必须发送一个Origin标题来告诉维基百科你来自哪里。维基百科正在管理访问,而不是你。

发送此原始标题:

xhr.setRequestHeader("Origin", "http://www.yourpage.com");

Access-Control-Allow-*标头是响应标头,而不是请求标头。

维基百科还需要内容类型为json:

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

答案 3 :(得分:5)

您可以使用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) { ... }
}

答案 4 :(得分:0)

仅对网址添加origin=*对我不起作用,因此添加了withCredentials=false。它将起作用。

Those whoever facing issue again after adding `origin=*` . Try below one with `withCredentials = false`

var xhttp = new XMLHttpRequest();
var url = "https://en.wikipedia.org/w/api.php?action=opensearch&limit=5&origin=*&search=simple";
xhttp.onreadystatechange = function () {
    if (readyState == 4 && status == 200) {
        console.log(responseText)
    }
};
xhttp.open("GET", url, true);
xhttp.withCredentials = false;
xhttp.setRequestHeader("Content-type", "application/json; charset=utf-8");
xhttp.send();

@muraliv的积分