这不是 what-are-differences-between-xmlhttprequest-and-httprequest 的副本 对于信息,我尝试了 this lib没有成功,因为它复制了 XMLHttpRequest 的结构,但实际上并不像它那样。
我想知道来自 Node 的 HttpRequest 和来自浏览器的 XMLHttpRequest 之间真正的网络区别是什么。
如果我只是在 chrome 的 devtools 中查看 XMLHttpRequest,我在请求中看不到任何 X-Requested-with header 。
此外,CloudFlare 的 WAF 背后还有一个在线服务,带有自定义规则。如果我使用 XMLHttpRequest 发出请求,它就可以正常工作,但我使用 https.request 进行请求时,它无法通过 CF 进行防火墙保护。
我需要使用 HttpRequest 来完成它,这样我就可以配置代理。
两者之间的网络有什么区别,我如何从 HttpRequest 模拟 XMLHttpRequest ?这可能吗? 我看了 Chrome 源here但找不到任何有趣的东西。
也许它与 IO 层不同? TCP 握手?
需要建议。谢谢
这是 XMLHttpRequest(工作)
let req = new XMLHttpRequest();
req.open("post", "https://haapi.ankama.com/json/Ankama/v2/Api/CreateApiKey", true);
req.withCredentials = true;
req.setRequestHeader('Accept', 'application/json');
req.setRequestHeader('Content-Type', 'text/plain;charset=UTF-8');
req.setRequestHeader('Accept-Encoding', 'gzip, deflate, br');
req.onload = function() {
console.log(req.response)
};
req.send("login=smallladybug949&password=Tl9HDKWjusopMWy&long_life_token=true");
和cURL一样(不通过CF的防火墙)
curl 'URL' \
-H 'origin: null' \
-H 'accept-encoding: gzip, deflate, br' \
-H 'user-agent: Mozilla/5.0 (Linux; Android 6.0.1; Z988 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/69.0.3497.100 Mobile Safari/537.36' \
-H 'content-type: text/plain;charset=UTF-8' \
-H 'accept: application/json' \
-H 'authority: URL.com' \
--data-binary 'login=123&password=def' \
--compressed
这是 HttpRequest(没有通过 CF 的防火墙)
let opts = url.parse(URL);
opts.method = post;
opts.headers = {
'Accept': 'application/json',
'Content-Type': 'text/plain;charset=UTF-8',
'Accept-Encoding': 'gzip, deflate, br',
'User-Agent': 'Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.137 Mobile Safari/537.36'
}
let req = https.request(opts, function (res) {
res.setEncoding('utf8');
res.body = "";
res.on('data', (chunk) => {
res.body += chunk;
});
res.on('end', (chunk) => {
try {
res.body = JSON.parse(res.body);
} catch (e) {
return reject(res.body); // error, http 403 / 1020 error from CF (custom FW rule)
}
console.log(res.body); // we'll not reach this
});
});
req.on('error', e => {
console.error('error', e);
});
req.write("login=abc&password=def");
req.end();
经过多次测试,curl 命令可以正常工作,XHR 也可以,但是对于 Postman 或 HttpRequest,它会失败。 这是 postman vs curl 的视频:https://streamable.com/81s57 视频中的 curl 命令是这个:
curl -X POST \
https://haapi.ankama.com/json/Ankama/v2/Api/CreateApiKey \
-H 'accept: application/json' \
-H 'accept-encoding: gzip, deflate, br' \
-H 'accept-language: fr' \
-H 'authority: haapi.ankama.com' \
-H 'content-type: text/plain;charset=UTF-8' \
-H 'origin: null' \
-H 'user-agent: Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.137 Mobile Safari/537.36' \
-d 'login=smallladybug949&password=Tl9HDKWjusopMWy&long_life_token=true'
(这是一个测试帐户,所以我不需要它,您可以用它进行测试)。您可以将 --compressed 标志添加到 curl 请求以将其解压缩或将其通过管道传输到 gunzip。
我发现这是由于误用了(对于 CF)TLS 协议(protocol)。通过降级使用 OpenSSL/1.1.0f 的 curl,调用就可以正常工作。但自 OpenSSL/1.1.0g 以来,他们没有。 您可以阅读有关 OpenSSL 变更日志的更多信息 here
最佳答案
正如我在评论中讨论的那样,我可以重现:来自第一个“编辑”的 XMLHttpRequest 示例有效(HTTP 状态 = 200),而它的“复制为 cURL”版本从 Cloudfare 返回 403。
正在添加 --cert-status curl 使它对我有用,因此 Cloudfare 在决定拒绝请求时似乎分析了 TLS 级别的通信。
第一次编辑中的 curl 命令与我使用“复制为 cURL”时获得的版本有一些其他差异:
curl 'URL' 而不是 https://haapi.ankama.com/json/Ankama/v2/Api/CreateApiKey 显然失败了,请不要制作更难重现您的结果。-H 'origin: null' vs -H 'Origin: https://localhost:4443' -H 'Referer: https://localhost:4443/test_http.html ' - 这没什么区别。-H 'DNT: 1' -H 'Connection: keep-alive' -H 'Cookie: __cfduid=dcf1b80eef19562054c9b64f79139509e1566138746' 也没有什么区别。 -H 'user-agent: - 也不影响 Cloudfare-H 'authority: URL.com'(用占位符代替真实域),这也没有什么区别。--data-binary 'login=123&password=def' 只影响API结果;不影响 403。-H 'Accept-Language: header 会导致来自 Cloudfare 的 403。因此您可以尝试将缺少的 Accept-Language 添加到 Node 版本中,看看是否有帮助。
我的 Node 版本不在 TLS Client Hello 中发送 Extension: status_request(这似乎是有或没有 --cert-status 的 curl 调用之间的区别>),我不知道您将如何启用它。在这一点上,如果可能的话,我会尝试联系支持人员,或者回退到从节点调用 curl。
附言在调试它时,我尝试比较 curl 与浏览器的 Wireshark 捕获(节点不支持 SSLKEYLOGFILE,forcing you to jump through hoops, so I didn't even try checking how its capture looks)。细微差别如此之多,以至于尝试对 Cloudfare 使用的规则进行逆向工程将非常耗时。 --cert-status 是一个幸运的猜测。
Firefox/curl/node 中的 SSL Client Hello 非常不同:
Firefox
curl
node11
关于javascript - HttpRequest 和 XMLHttpRequest 之间的真正区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57436880/
我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此
请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是
在Cooper的书BeginningRuby中,第166页有一个我无法重现的示例。classSongincludeComparableattr_accessor:lengthdef(other)@lengthother.lengthenddefinitialize(song_name,length)@song_name=song_name@length=lengthendenda=Song.new('Rockaroundtheclock',143)b=Song.new('BohemianRhapsody',544)c=Song.new('MinuteWaltz',60)a.betwee
我正在检查一个Rails项目。在ERubyHTML模板页面上,我看到了这样几行:我不明白为什么不这样写:在这种情况下,||=和ifnil?有什么区别? 最佳答案 在这种特殊情况下没有区别,但可能是出于习惯。每当我看到nil?被使用时,它几乎总是使用不当。在Ruby中,很少有东西在逻辑上是假的,只有文字false和nil是。这意味着像if(!x.nil?)这样的代码几乎总是更好地表示为if(x)除非期望x可能是文字false。我会将其切换为||=false,因为它具有相同的结果,但这在很大程度上取决于偏好。唯一的缺点是赋值会在每次运行
我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是
📢博客主页:https://blog.csdn.net/weixin_43197380📢欢迎点赞👍收藏⭐留言📝如有错误敬请指正!📢本文由Loewen丶原创,首发于CSDN,转载注明出处🙉📢现在的付出,都会是一种沉淀,只为让你成为更好的人✨文章预览:一.分辨率(Resolution)1、工业相机的分辨率是如何定义的?2、工业相机的分辨率是如何选择的?二.精度(Accuracy)1、像素精度(PixelAccuracy)2、定位精度和重复定位精度(RepeatPrecision)三.公差(Tolerance)四.课后作业(Post-ClassExercises)视觉行业的初学者,甚至是做了1~2年
转自:spring.profiles.active和spring.profiles.include的使用及区别说明下文笔者讲述spring.profiles.active和spring.profiles.include的区别简介说明,如下所示我们都知道,在日常开发中,开发|测试|生产环境都拥有不同的配置信息如:jdbc地址、ip、端口等此时为了避免每次都修改全部信息,我们则可以采用以上的属性处理此类异常spring.profiles.active属性例:配置文件,可使用以下方式定义application-${profile}.properties开发环境配置文件:application-dev
打印1:defsum(i)i=i+[2]end$x=[1]sum($x)print$x打印12:defsum(i)i.push(2)end$x=[1]sum($x)print$x后者是修改全局变量$x。为什么它在第二个例子中被修改而不是在第一个例子中?类Array的任何方法(不仅是push)都会发生这种情况吗? 最佳答案 变量范围在这里无关紧要。在第一段代码中,您仅使用赋值运算符=为变量i赋值,而在第二段代码中,您正在修改$x(也称为i)使用破坏性方法push。赋值从不修改任何对象。它只是提供一个名称来引用一个对象。方法要么是破坏性
Ruby中的Fixnum方法.next和.succ有什么区别?看起来它的工作原理是一样的:1.next=>21.succ=>2如果有什么不同,为什么有两种方法做同样的事情? 最佳答案 它们是等价的。Fixnum#succ只是Fixnum#next的同义词。他们甚至在thereferencemanual中共享同一block. 关于ruby-Ruby中.next和.succ的区别,我们在StackOverflow上找到一个类似的问题: https://stacko
我明白了defa(&block)block.call(self)end和defa()yieldselfend导致相同的结果,如果我假设有这样一个blocka{}。我的问题是-因为我偶然发现了一些这样的代码,它是否有任何区别或者是否有任何优势(如果我不使用变量/引用block):defa(&block)yieldselfend这是一个我不理解&block用法的具体案例:defrule(code,name,&block)@rules=[]if@rules.nil?@rules 最佳答案 我能想到的唯一优点就是自省(introspecti