我正在编写一个个人 Chrome 扩展程序(注意:这些可以发出跨源请求。请参阅 https://developer.chrome.com/extensions/xhr)。
我正在尝试使用 XMLHttpRequest 访问某个网站,然后使用 javascript 从中提取数据。我的问题是该网站经常将其“机器人”页面而不是 HTML 返回给我。当然,当我在浏览器中访问这个网站时,它工作正常。此外,如果我使用浏览器访问该网站,然后发出 XHR 请求,它也可以正常工作。
我认为问题可能是我的请求 header 不正确。然后我修改了我的请求 header ,使它们与我的浏览器相同(使用 chrome.webRequest)。不幸的是,这也不起作用。我注意到的一件事是我的浏览器在其请求 header 中有一些 cookie,我不知道如何复制它们(见下文)。
因此,我的问题是:如何解决或调试这个问题?有没有办法找出为什么该网站向我提供其“机器人”页面?如果我查看它的 robots.txt 文件,我并没有违反任何明显的规则。我是 javascript 和网络编程的新手,如果这是一个基本问题,我很抱歉。
这是我的浏览器请求 header 的示例:
GET /XXX/XXX HTTP/1.1
Host: www.example.com
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8
Referer: https://www.example.com/XXX
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cookie: D_IID=XXX-XXX-XXX-XXX-XXX; D_UID=XXX-XXX-XXX-XXX-XXX; D_ZID=XXX-XXX-XXX-XXX-XXX; D_ZUID=XXX-XXX-XXX-XXX-XXX; D_HID=XXX-XXX-XXX-XXX-XXX; D_SID=XXX/XXX/XXX
更新
我还包括在 Chrome 中定义的“常规” header :
Request URL: https://www.example.com/XXX
Request Method: GET
Status Code: 200 OK
Remote Address: XXX
Referrer Policy: no-referrer-when-downgrade
还有我的响应头:
Cache-Control: private, no-cache, no-store, must-revalidate
Connection: keep-alive
Content-Encoding: gzip
Content-Type: text/html
Date: Wed, 06 Feb 2019 XXX GMT
Edge-Control: no-store, bypass-cache
Expires: Thu, 01 Jan 1970 00:00:01 GMT
Server: XXX
Surrogate-Control: no-store, bypass-cache
Transfer-Encoding: chunked
Vary: Accept-Encoding
X-DB: 0
X-DW: 0
X-DZ: XXX
更新 2
查看响应 HTML 后,我不确定它是什么。我最初认为这是某种 ROBOTS 响应,因为它说 META NAME="ROBOTS",但现在我不太确定了。这是 HTML 的一般结构。
<!DOCTYPE html>
<html>
<head>
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
<meta http-equiv="cache-control" content="max-age=0" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="expires" content="0" />
<meta http-equiv="expires" content="Tue, 01 Jan 1980 XXX GMT" />
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="refresh" content="10; url=example.com" />
<script type="text/javascript">
// SOME JAVASCRIPT
</script>
<script type="text/javascript" src="/example.js" defer></script></head>
<body>
<div id="XXX"> </div>
</body>
</html>
最佳答案
当我查看您的用户代理时,您正在使用 Mac 和 Apple 产品。
一些背景信息,Chrome 使用 Safari 的渲染引擎,因为 Apple 不允许其他引擎,Apple 政策。事实上,Chrome 只是一个 GUI 盾牌,看起来像 Chrome,但骨架仍然是 Safari。这就是为什么当 Safari 引擎出现问题时,您无法解决问题。当核心出现问题时,安装另一个浏览器无济于事。你遇到的问题是其中之一,悲伤但真实。 让我解释一下。
过去,将(对象/iframe)嵌入到网站中的(Luondo)网上商店也有类似的问题,也启用了跨策略等,但在 Apple 设备上不起作用(仅!)。只有 Apple 用户需要先访问网上商店的域,他们才能下订单(正如您所描述的那样,cookie 问题)。这是某种愚蠢的安全相关策略,仅在使用 Safari(或使用其所需的嵌入式引擎)时存在。
我所做的(但我认为对您的情况没有帮助)是在检测到 Apple 设备时在页面上添加一条消息。该消息包含指向将在另一个标签页中打开的网店域的链接。在此之后,苹果用户就可以下单了。另请参阅此荷兰语消息(翻译如下):
Apple 用户请注意:
Safari 存在安全问题,首先您必须访问我们的网店提供商一次才能下订单。
单击以下链接打开我们的网店提供商的网站,然后您可以将其关闭:[link]在 Apple 设备上激活订单功能[/link]
对于给您带来的不便,我们深表歉意。
虽然不是最好的翻译,但我想您明白了。这是(从现在开始,2019 年)两年前,问题仍然存在,就像你向我们展示的那样。
----------------
解决方案:
无论如何,是否有解决方案,可能不适用于 Apple 用户(因为 Apple 需要修复此问题)但是,您是否在安装了 Chrome 的 Linux/Windows 机器上尝试过?我敢打赌它会起作用,除非有一些安全限制服务器站点可以避免 ajax 调用,但是,我认为没有问题。
另一种方法:
1。我不知道你的技能,但是你可以考虑设置一个代理服务器来避免这些问题,将网站的内容嵌入(或更好地包括)到你的输出(包括 cookies)中。一个警告,这可能是非法的,因为您将另一个网站的内容合并为您自己的内容;
2。询问他们为其服务提供 API 的网站所有者。
个人对ajax方法的看法:
如果您想“合并”html 或提取不属于您自己的另一个站点(通过使用 javascript)的内容(如您所说),我怀疑您尝试做的是合法的。我认为这也是您不想提及“服务”的名称/域名的原因(示例不是我想的服务)。试着弄清楚你想做什么实际上是合法的,如果不是,这一切都是浪费时间,除非像我上面解释的那样有一个 API。
也许这一切听起来不像是一个答案,但它会让您(希望)对实际问题有一些了解。
祝你周六愉快,希望对你有所帮助。
关于javascript - 为什么我的 XMLHttpRequest 收到 robots.txt 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54528445/