【问题标题】:No 'Access-Control-Allow-Origin' header is present. Origin is therefore not allowed access不存在“Access-Control-Allow-Origin”标头。因此不允许 Origin 访问
【发布时间】:2015-09-30 06:50:47
【问题描述】:

编辑:没有 JSONP!是的,我知道 CORS 是由服务器处理的,是的,服务器确实支持它。问题在我这边。

我正在尝试从浏览器中使用 MediaWiki API。我正在通过 XMLHttpRequest 发送 GET 请求,但由于 CORS 问题,它无法正常工作。收到响应后,我的浏览器收到以下消息:

XMLHttpRequest 无法加载 https://en.wikipedia.org/w/api.php?format=json&action=query&list=search&srsearch=Oculus&utf8。请求的资源上不存在“Access-Control-Allow-Origin”标头。 Origin 'http://127.0.0.1:8000' 因此不允许访问。

我明白为什么会遇到这个问题,但我不知道如何从浏览器/JavaScript 端解决它。

代码:

xmlhttp.open("GET","https://en.wikipedia.org/w/api.php?format=json&action=query&list=search&srsearch=" + subreddit + "&utf8",true);
xmlhttp.setRequestHeader("Content-Type", "application/json; charset=UTF-8");
xmlhttp.send();

我尝试过的一些事情:

xmlhttp.setRequestHeader('Access-Control-Allow-Origin', 'http://localhost');
xmlhttp.setRequestHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
xmlhttp.setRequestHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
xmlhttp.setRequestHeader('Access-Control-Allow-Credentials', true)
xmlhttp.setRequestHeader("Content-Type", "application/json; charset=UTF-8");

并在 url 中设置参数 origin 或作为 setRequestHeader 返回无效/错误的 Origin,被拒绝。

【问题讨论】:

  • 所以我因为提出一个有效的问题而被否决了? “重复”问题提供了解决方案,例如使用 JSONP,这不是我想要的。其他答案说要设置标题或显然是错误的。重新迭代我不想使用 JSONP。最佳答案链接到使用 XDomainRequest() 而不是 XMLHttpRequest() 的博客。经过比较,似乎需要 XDomainRequest() 来实现 CORS 兼容性。
  • 那么那个“重复”问题的答案都不是有效的。
  • JSONP 不能解决问题,它只是绕过了 CORS 问题。 MediaWiki 支持 CORS,所以我不知道为什么会遇到这个浏览器问题。

标签: javascript http cors mediawiki mediawiki-api


【解决方案1】:

您可以使用 JSONP。

<script src='https://en.wikipedia.org/w/api.php?format=json&action=query&list=search&srsearch=Oculus&utf8&callback=callbackname'></script>
<script>
    function callbackname(data){
       //you can get response data here
    }
</script>

如果你使用 jquery。

$.getJSON('https://en.wikipedia.org/w/api.php?format=json&action=query&list=search&srsearch=Oculus&utf8&callback=?', function(data){
    //you can get response data here
})

【讨论】:

  • 有没有 JSONP 方式来处理这个 CORS 问题?从我读过的内容来看,这似乎是一种绕过问题而不真正解决问题的骇人听闻的方式。
  • 唯一的 CORS 问题是他们不发出 CORS 标头,而您希望它们发出
  • JSONP 也不是一个解决方案,因为回调参数没有记录在他们的 API 中
  • 我已经做到了,但它不起作用。我尝试设置许多 http 标头,但都没有解决问题。以上面编辑的代码为例。
  • 想通了,因为在我在这里提到它之前尝试它时它不起作用。
【解决方案2】:

here 所述,您在请求中传递的 origin 参数和浏览器在 AJAX 调用中发送的 Origin 标头应该匹配,并且它必须匹配$wgCrossSiteAJAXdomains 在国外维基。由于您的 Origin(在您的情况下为 http://127.0.0.1:8000 或 localhost:8000)在 $wgCrossSiteAJAXdomains 中不可用,MediaWiki API 将永远不会在响应中发送 Access-Control-Allow-Origin 标头,并且任何 CORS 请求都将失败,并显示您的错误在浏览器的控制台中查看。

另一个需要考虑的重要事实是

MediaWiki API 用于 Wikimedia 网站上执行诸如允许图像之类的操作 从移动设备上的维基百科网站直接上传到 Commons 界面。

此 API 不适用于任何主机的公共使用,它仅适用于一组经过验证的主机。

如果你想尝试一些 CORS 请求,你可以使用来自here 的 GitHub API。 这是一个示例 pen 向 GitHub API 发出 CORS 请求,并将 JSON 响应记录到 DevTools 控制台。

【讨论】:

  • 但是,CORS 的问题不是我的浏览器实现的安全问题吗?为什么存在允许 CORS 的服务器端来源白名单?根据我对 CORS 的了解,我的浏览器向 A 发送请求,但响应是从 B 发送的,因此它不接受要读取的响应。我误解了这个问题吗?
  • 不。 CORS 是关于跨域请求的。由于同源策略,来自域 A 的脚本无法对域 B 进行 AJAX 调用。 CORS 放宽了此限制,以便域 A 脚本可以调用域 B,但由域 B 响应该请求。如果 B 信任 A,那么它将发送 Access-Contol-Allow-* 标头并且浏览器可以处理响应。另一方面,如果 B 不知道 A,它不会发送 CORS 特定的 headers,浏览器会抛出错误
【解决方案3】:

目前无法做您想做的事,因为有一个允许 CORS 的服务器端来源白名单,而您的服务器不在白名单上。

目前 MediaWiki 中没有针对无身份验证 CORS 的选项,因此白名单适用于所有 CORS 请求,无论它们是否包含身份验证。

https://phabricator.wikimedia.org/T62835https://www.mediawiki.org/wiki/Manual:CORS

【讨论】:

  • 但是 CORS 的问题不是我的浏览器实现的安全问题吗?为什么存在允许 CORS 的服务器端来源白名单?根据我对 CORS 的了解,我的浏览器向 A 发送请求,但响应是从 B 发送的,因此它不接受要读取的响应。我误解了这个问题吗?
猜你喜欢
  • 1970-01-01
  • 2013-12-24
  • 2017-02-04
  • 2014-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-09
相关资源
最近更新 更多