【问题标题】:Access-Control-Allow-Origin with Wikipedia API with JavascriptAccess-Control-Allow-Origin with Wikipedia API with Javascript
【发布时间】:2024-05-21 12:30:02
【问题描述】:

试图从 Codepen 上的 Wikipedia API 接收响应。回复应该是我正在尝试 console.log 的 json。

在控制台中我看到一个错误:

跨域请求被阻止:同源策略不允许读取位于https://en.wikipedia.org/w/api.php?action=opensearch&search=earth&format=json 的远程资源。 (原因:CORS 标头“Access-Control-Allow-Origin”缺失)。

在过去的几天里,我读了很多关于 CORS 和 Allow-Origin 的文章以试图理解,但出于某种原因,即使我认为我理解了......我无法实现 :)

然而,最有趣的是——即使控制台显示这样的错误消息,如果我查看开发人员工具网络选项卡中的实际响应,我还是看到了 json 响应的全部荣耀!

最好能解释一下这怎么可能?

Codepen 链接here

var xhrObject = new XMLHttpRequest();

xhrObject.onreadystatechange = function() {
  if (xhrObject.readyState === 4 && xhrObject.status === 200) {
      console.log(xhrObject.responseText); 
    }
};

xhrObject.open(
  "POST", "https://en.wikipedia.org/w/api.php?action=opensearch&search=earth&format=json", true
);
xhrObject.send();

提前致谢

【问题讨论】:

    标签: javascript json cors wikipedia-api


    【解决方案1】:

    然而,最有趣的是——即使控制台显示这样的错误消息,如果我查看开发人员工具网络选项卡中的实际响应,我还是看到了 json 响应的全部荣耀!

    最好能解释一下这怎么可能?

    同源政策的目的是防止 Mallary(恶意网站的作者)使用 Alice 的网络浏览器(该浏览器具有 Alice 的 cookie 和 Alice 的 IP 地址以及将其识别为 Alice 的 strong> 浏览器)从 Bob 的网站(可能是 Alice 的网上银行或公司内部网)读取秘密数据。

    不允许 Mallary 的 JavaScript 访问数据,除非 Bob 告诉 Alice 的浏览器让 JS 读取数据是安全的(使用 CORS)。

    允许 Alice 的浏览器访问数据,因为 Bob 已经信任 Alice 拥有数据。 Mallary 无法访问 Alice 浏览器中的开发者工具。

    【讨论】:

    • 所以 Wiki API 信任我的浏览器,但我无法从 Codepen 访问它,因为它尚未获得批准?这是如何完成的,通过添加带有什么域的请求标头? Codepens 还是 Wiki?
    • *必须这样做。如果您能够允许自己,那就太愚蠢了。
    【解决方案2】:

    origin=* 添加到您使用的* URL 的查询参数中,请求将起作用。

    要使对 Wikipedia API 的 JavaScript Fetch/XHR 请求正常工作,您必须在 URL 查询参数中包含 origin=* - per the CORS-related docs for the Wikipedia backend

    对于匿名请求,origin 查询字符串参数可以设置为*,这将允许来自任何地方的请求。

    所以问题中的网址应该是这样的:

    "https://en.wikipedia.org/w/api.php?action=opensearch&origin=*&search=earth&format=json"
    

    …甚至像这样:

    "https://en.wikipedia.org/w/api.php?action=opensearch&origin=*&search=earth="
    

    (也就是说,我认为您可以省略 format=json,因为 JSON 输出似乎是默认值。)

    【讨论】:

      【解决方案3】:

      添加origin=* 后再次遇到问题的人。试试下面的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();
      

      【讨论】: