我正在尝试使用 POST XMLHttpRequest 从 wikidata API 获取查询结果。但只有很少的请求通过,还有一些返回 CORS 问题错误,这非常令人困惑。
我的请求看起来像这样,我已经在 url 本身中设置了 origin 参数,正如我从 wikidata 文档中理解的那样。我也尝试过在标题中设置原点,但这也不起作用。
setTimeout(function () {
var xhr = new XMLHttpRequest();
xhr.open(
"POST",
"https://query.wikidata.org/sparql?origin=*&format=json&query=" +
encodeURIComponent(
queryService(settingsService()).getPropObject(
vm.selected.uri,
prop
)
),
true
);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
let data = JSON.parse(xhr.response);
setObjectInnerHtml(label, data, prop);
}
running -= 1;
};
xhr.send();
}, 300);
但它在 xhr.send() 处返回错误,如下所示:
Access to XMLHttpRequest at 'https://query.wikidata.org/sparql?origin=*&format=json&query=PREFIX%20rdf%3A%20%3Chttp%3A%2F%2Fwww.w3.org%2F1999%2F02%2F22-rdf-syntax-ns%23%3E%0APREFIX%20rdfs%3A%20%3Chttp%3A%2F%2Fwww.w3.org%2F2000%2F01%2Frdf-schema%23%3E%0ASELECT%20DISTINCT%20%3Furi%20%3FuriLabel%20WHERE%20%7B%0A%20%20%3Chttp%3A%2F%2Fwww.wikidata.org%2Fentity%2FQ183%3E%20%3Chttp%3A%2F%2Fwww.wikidata.org%2Fprop%2Fdirect%2FP1889%3E%20%3Furi%20.%0A%20%20OPTIONAL%20%7B%20%3Furi%20rdfs%3Alabel%20%3FuriLabel%20.%20FILTER%20(lang(%3FuriLabel)%20%3D%20%22en%22)%7D%0A%7D' from origin 'http://localhost:8000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
这里可能出了什么问题?
更新 这是同一个方法发出的一系列请求,可以看到有的请求通过了,有的没有通过。抛出的错误是 CORS 问题。
好吧,我实际上已经看到这种情况发生在我身上(不是在维基百科上),而是在其他 API 服务器上,包括我自己的一些服务器上。
经过一番努力并尝试排除其他因素(我尝试在本地主机和多台计算机上运行代码),这就是我发现的。
问题出在我的 ISP 上。我的本地 ISP 有一个不可靠的 DNS 服务器,连接会停止并开始工作,有时每隔几秒钟就会重复一次。有时,在一秒钟之内,就会出现任意数量的快速连接和断开。每次发生这种情况时,控制台都会不断抛出 CORS 错误,即使它与 CORS 本身无关。
此外,当我从本地主机部署此应用程序到云时,我从未遇到任何问题。显然,云服务器的互联网连接问题为零。
总而言之,如果您间歇性地收到 CORS 错误(正如您所描述的),我首先会确保您的互联网连接可靠。
然后,将代码部署到在线云服务器,看看问题是否重现。
请注意:我假设您在屏幕截图中提到的呼叫在所有可能的方面都是相同的。就我而言,问题发生在具有相同负载数据的相同调用上。
如果您在本地开发中仍然遇到此问题,我可以通过添加 User-Agent 标头并使用 User-Agent Mozilla 文档 中的 UA 字符串来解决该问题。
在 wikiadata 文档 中写道:
不遵守用户代理策略的客户端可能会被完全阻止 - 请确保发送良好的用户代理标头。
例如:
const res = await fetch(
`https://query.wikidata.org/bigdata/namespace/wdq/sparql?query=${query}`,
{
headers: {
Accept: 'application/sparql-results+json',
'User-Agent':
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36',
},
}
)