Wikipedia API 支持 CORS 还是仅支持 JSONP?

2022-01-15 00:00:00 cors jquery javascript jsonp wikipedia-api

这个问题与一年前提出的另一个问题有关.作者询问如何使用 JavaScript 和 Wikipedia API 进行跨域请求,其中一条评论是:

This question related to another question, which was asked year ago. Author asked how to make cros-origin request using JavaScript and Wikipedia API and one comment was:

en.wikipedia.org 似乎不允许 CORS

en.wikipedia.org doesn't seem to allow CORS

建议他改用 JSONP.

and he was advised to use JSONP instead.

我知道我可以使用 JSONP,但如果可以的话,我更喜欢 CORS.

I know I can use JSONP, but I prefer CORS if I can use it.

我试过 jsfiddle

var url = "https://en.wikipedia.org/w/api.php?action=query&titles=Main%20Page&prop=revisions&rvprop=content&format=json";

                $.ajax({
                    url: url,
                    data: 'query',
                    dataType: 'json',
                    type: 'POST',
                    headers: { 'Api-User-Agent': 'Example/1.0' },
                    origin: 'https://jsfiddle.net/',
                    success: function (data) {
                        console.log(data);
                        //do something with data
                    }});

并得到以下错误:

XMLHttpRequest 无法加载https://en.wikipedia.org/w/api.php?action=query&titles=Main%20Page&prop=revisions&rvprop=content&format=json.对预检请求的响应未通过访问控制检查:否请求中存在Access-Control-Allow-Origin"标头资源.因此,来源 'https://fiddle.jshell.net' 是不允许的访问.

XMLHttpRequest cannot load https://en.wikipedia.org/w/api.php?action=query&titles=Main%20Page&prop=revisions&rvprop=content&format=json. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://fiddle.jshell.net' is therefore not allowed access.

请求标头:

authority:en.wikipedia.org
method:OPTIONS
path:/w/api.php?action=query&titles=Main%20Page&prop=revisions&rvprop=content&format=json
scheme:https 
accept:/ 
accept-encoding:gzip, deflate, sdch 
accept-language:en-US,en;q=0.8,fr-CA;q=0.6,fr;q=0.4,fr-FR;q=0.2,ru;q=0.2,uk;q=0.2 
access-control-request-headers:accept, api-user-agent, content-type 
access-control-request-method:POST 
origin:https://fiddle.jshell.net 
referer:https://fiddle.jshell.net/_display/ 
user-agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36

响应标头:

accept-ranges:bytes 
age:0 
backend-timing:D=33198 t=1462749020308717 
cache-control:no-cache 
content-encoding:gzip 
content-length:20 
content-type:text/html 
date:Sun, 08 May 2016 23:10:20 GMT 
p3p:CP="This is not a P3P policy! See https://en.wikipedia.org/wiki/Special:CentralAutoLogin/P3P for more info." 
server:mw1114.eqiad.wmnet 
set-cookie:CP=H2; Path=/; secure 
set-cookie:GeoIP=US:MA:Waltham:42.37:-71.24:v4; Path=/; secure; Domain=.wikipedia.org 
set-cookie:WMF-Last-Access=08-May-2016;Path=/;HttpOnly;secure;
Expires=Thu, 09 Jun 2016 12:00:00 GMT 
status:200 
strict-transport-security:max-age=31536000; includeSubDomains; preload 
vary:Accept-Encoding 
via:1.1 varnish, 1.1 varnish 
x-analytics:https=1;nocookies=1 
x-cache:cp1066 pass+chfp(0), cp1055 frontend pass+chfp(0) 
x-client-ip:146.115.167.51 
x-content-type-options:nosniff 
x-powered-by:HHVM/3.12.1 
x-varnish:2807049448, 2537048470

所以,我需要确认 CORS 不适用于 Wikipedia API,我需要使用 JSONP.

So, I need confirmation that CORS doesn't work for Wikipedia API and I need use JSONP.

推荐答案

要向 Wikipedia 发出 JavaScript Fetch/XHR 请求,请将 origin=* 添加到 URL 查询参数中.

To make JavaScript Fetch/XHR requests to Wikipedia, add origin=* to the URL query params.

所以问题中 URL 的基础应该是这样的:

So the base of the URL in the question should be like this:

https://en.wikipedia.org/w/api.php?origin=*&action=query…

请参阅维基百科后端的 CORS 相关文档:

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

For anonymous requests, origin query string parameter can be set to * which will allow requests from anywhere.

<小时>

2016-05-09 原答案

请参阅在 API 的 JSON 响应中启用跨域 API 请求",这是 Wikimedia 网站的一个开放错误这表明它们目前仅支持来自不同维基媒体站点本身向其他维基媒体站点发出的 CORS 请求,但它们不支持来自外部站点的 CORS 请求.


2016-05-09 original answer

See "Enable cross-domain API requests in API's JSON responses", an open bug for Wikimedia sites that indicates that they currently only support CORS requests from different Wikimedia sites themselves to other Wikimedia sites—but they do not support CORS requests from external sites.

具体参见https://phabricator.wikimedia.org/T62835#2191138(来自2016 年 4 月 8 日)这是一个摘要,表明他们正在考虑进行更改以允许来自外部站点的 CORS 请求,但他们尚未启用它.

See in particular https://phabricator.wikimedia.org/T62835#2191138 (from Apr 8, 2016) which is a summary that indicates they are considering to make a change to allow CORS request from external sites, but they have not yet enabled it.

他们似乎将今天部署 CORS 支持:

现在可以进行未经身份验证的跨域 API 请求.这应该使用 1.128.0-wmf.10 部署到 WMF wiki,请参阅https://www.mediawiki.org/wiki/MediaWiki_1.28/Roadmap时间表

unauthenticated cross-domain API requests are now possible. This should be deployed to WMF wikis with 1.128.0-wmf.10, see https://www.mediawiki.org/wiki/MediaWiki_1.28/Roadmap for the schedule

https://www.mediawiki.org/wiki/MediaWiki_1.28/Roadmap 表示 1.128.0-wmf.10 部署日期为 2016 年 7 月 12 日至 2016 年 7 月 14 日.

https://www.mediawiki.org/wiki/MediaWiki_1.28/Roadmap indicates the 1.128.0-wmf.10 deployment dates are 12 July 2016 to 14 July 2016.

作为 torvin 注释 在下面的评论中:

要触发新行为,您需要在 url 参数中指定 origin=*.这目前隐藏在 T62835 讨论中,并且未在 文档.

to trigger the new behaviour, you need to specify origin=* in your url params. This is currently buried in the T62835 discussion and is not stated in the documentation yet.

相关文章