How to stop NodeJS "Request" module changes request when using proxy

时间:2019-03-19 14:54:25

标签: javascript node.js proxy request http-proxy

Sorry if this comes off as confusing.

I have written a script using the NodeJS request module that runs and performs a function on a website then returns with the data. This script works perfectly fine when I do not use a proxy by setting it to false. This is not a task that is NOT allowed to be done with Selenium/puppeteer

proxy: false

However, when I set a (working) proxy. It fails to perform the same task and is detected by the website firewall/antibot software.

proxy: http://xx.xxx.xx.xx:3128

Some things to note:

  • I have tried many (20+) different proxy providers (Residential and Datacenter) and they all have this issue
  • The issue does not occur if that proxy is set globally on my system
  • The issue does not occur if that proxy is set in a chrome extension
  • The SSL cipher suites do not match Chrome but they still don't match when not using a proxy so I assume that isn't the issue
  • It is very important to keep consistency in the header order

The question basically is. Does the request module change anything when using a proxy such as the header order?

Here is an image of what happens when it passes/fails. enter image description here

The only difference is changing the proxy that causes this to fail. One request being made with, one request being made without.

url    : url,
simple : false,
forever: true,
resolveWithFullResponse: true,
gzip: true,
headers: {
    'Host'             : 'www.sitename.com',
    'Connection'       : 'keep-alive',
    'Upgrade-Insecure-Requests': '1',
    'User-Agent'       : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36',
    'Accept'           : 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
    'Accept-encoding'  : 'gzip, deflate, br',
    'Accept-Language'  : 'en-GB,en-US;q=0.9,en;q=0.8',
},
method : 'GET',
jar: globalJar,
simple: false,
followRedirect: false,
followAllRedirects: false, 

4 个答案:

答案 0 :(得分:2)

根据请求模块的the proxies documentation

  

默认情况下,代理HTTP流量时,请求将仅发出标准的代理HTTP请求。这是通过使请求的初始行的url部分成为指向端点的完全限定的url来完成的。

相反,您可以通过以下设置来使用http tunnel

tunnel : true

在请求模块代理设置中。

在您的情况下,您可能正在发出标准代理的http请求,而在系统或Chrome扩展程序上全局使用代理时, http隧道已创建。

从文档中:

  

请注意,在使用隧道代理时,代理授权头和自定义proxyHeaderExclusiveList中的任何头都不会发送到终结点服务器,而只会发送到代理服务器。

答案 1 :(得分:2)

停用旧帐户后,我想返回并给出此问题的实际答案,现在我完全理解了答案。一年前我问的是不可能的,Antibot正在通过TLS ClientHello(甚至在TCP /帧级别上略有指纹)对我进行指纹识别。

首先,我编写了一个名为request-curl的包装器,该包装器将libcurl / curl二进制文件包装为与request-promise相同格式的单个库,这使我对请求有了更多控制(防止编码,http2 / proxy支持以及进一步的会话/ TLS控制),这仍然只使我达到了第687个最受欢迎的ClientHello(https://client.tlsfingerprint.io:8443/)的medicore排名。这还不够好。

我不得不移动语言。 NodeJS太多是高级语言,无法进行真正的深度控制(必须修改从第3层发送的数据包)。因此,作为我的问题的答案。

这在NodeJS中尚不可能尚不能实现-更不用说 now 无需维护的request.js库了。

对于阅读本文的任何人,如果您想提出完美的请求来绕过反机器人安全性,则必须使用另一种语言:我建议使用Golang的utls或c#的BouncyCastle。真心感谢您,因为我花了一年的时间才真正做到了。即便如此,这些语言仍存在更多内部问题,并且尚不具备其功能(Go不支持“基本”标头排序,您需要猴子补丁/修改内部等,utls并不轻易支持代理)。清单不停。

如果您还不了解它,那真是个小坑,我建议您不要输入它。

答案 2 :(得分:0)

我可以想到一些场景

  • 代理实际上是在最终请求中添加一些标头(以便向服务器标识您)
  • 您尝试访问的网站已将您的代理IP(黑名单)(公开/付费)?

这实际上取决于您为什么需要使用该代理

  • 是因为网络限制吗?
  • 是因为要隐藏原始请求地址吗?

此外,如果您对代理服务器有控制权,可以将发出的请求记录到最终服务器上吗?

我的建议

尝试编写自己的代理(反向代理)并将其托管在某个地方。而不是请求https://target.com,而是请求您的http [s]://proxy.com/并让反向代理完成工作。 另外,请记住在实现上禁用X标头,因为它会更改请求标头

node.js实现参考:

https://github.com/nodejitsu/node-http-proxy

注意:让我知道我在评论中提出的问题

答案 3 :(得分:0)

您正在使用http方案来请求,但是如果网络服务器将http重定向到https,并且代理服务器未配置为接受重定向(到{ {1}}),那么问题可能仅与方案或您输入的URL有关。

因此必须将代理配置为接受重定向,否则在出现故障时必须手动检查URL,然后在发生重定向时进行调整。

在这里您可以了解有关一台代理服务器(Apache Traffic Server)上重定向的信息,该方案包含的重定向比我上面描述的还要多:
https://docs.trafficserver.apache.org/en/4.2.x/admin/reverse-proxy-http-redirects.en.html#handling-origin-server-redirect-responses

如果仍然遇到问题,则代理服务器的服务器日志会很有帮助。

编辑:
根据他的page @Jannes Botis的联系,仍然存在更多可能支持或破坏所需功能的代理设置,因此,整个问题可能与正确配置代理服务器有关。以下是与重定向直接相关的一些设置:

https

代理服务器的其他设置很有可能也会影响您方案的失败或成功。