HttpRequest 和 XMLHttpRequest 之间的真正区别

2024-05-25

阅读前注意事项

这不是重复的xmlhttprequest 和 httprequest 之间的区别是什么 https://stackoverflow.com/questions/8499062/what-are-differences-between-xmlhttprequest-and-httprequest作为信息,我尝试过this lib https://github.com/jbeuckm/node-XMLHttpRequest/blob/master/lib/XMLHttpRequest.js没有成功,因为它复制了 XMLHttpRequest 的结构,但实际上并不像它那样。


我想知道之间真正的网络区别是什么HttpRequest从节点和XMLHttpRequest从浏览器。

如果我只看 chrome 开发工具中的 XMLHttpRequest,我看不到任何X-Requested-with请求中的标头。

此外,CloudFlare 的 WAF 背后还有一个带有自定义规则的在线服务。如果我提出请求XMLHttpRequest,它只是有效,但我这样做https.requestCF 防火墙失败。

我需要这样做HttpRequest所以我可以配置代理。

两者之间的网络差异是什么,如何从 HttpRequest 模拟 XMLHttpRequest ?这可能吗? 我观察了铬的来源here https://chromium.googlesource.com/chromium/blink.git/+/99b8c9800ac123eddc3e199088d22569c5294b22/Source/core/xml/XMLHttpRequest.cpp但找不到任何有趣的东西。

也许它与 IO 层不同? TCP握手?

需要建议。谢谢


Edit

这是 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();

Edit 2

经过多次测试,curl 命令可以工作,XHR 也可以工作,但是使用 Postman 或 HttpRequest 时,它会失败。 这是邮递员与卷曲的视频:https://streamable.com/81s57 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.


编辑3(最终)

我发现这是由于滥用(CF)TLS 协议造成的。通过降级使用 OpenSSL/1.1.0f 的curl,调用就可以正常工作。但从 OpenSSL/1.1.0g 开始,他们就不再这样做了。 您可以阅读有关 OpenSSL 变更日志的更多信息here https://www.openssl.org/news/openssl-1.1.0-notes.html


正如我在评论中所讨论的,我可以重现:第一个“编辑”中的 XMLHttpRequest 示例有效(HTTP 状态 = 200),而其“复制为 cURL”版本则从 Cloudfare 返回 403。

Adding --cert-status https://ec.haxx.se/usingcurl-tls.html#ocsp-staplingtocurl 让它对我有用,所以 Cloudfare 在决定拒绝请求时似乎会分析 TLS 级别的通信。

第一次编辑时的curl 命令与我使用“Copy as 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'这也没有什么区别。
  • Varying -H 'user-agent:- 也不影响 Cloudfare
  • 你还有一个额外的-H 'authority: URL.com'(用占位符代替真实域),这也没有什么区别。
  • POST数据是否正确--data-binary 'login=123&password=def'只影响API结果;不影响403。
  • 失踪者-H 'Accept-Language:header 导致 Cloudflare 出现 403。

所以你可以尝试添加缺少的Accept-Language到 Node 版本看看是否有帮助。

我的 Node 版本无法发送Extension: status_request在 TLS Client Hello 中(这似乎是有或没有的卷曲调用之间的区别--cert-status),我不知道你如何启用它。此时,如果可能的话,我会尝试联系支持人员,或者回退到从节点调用curl。

附:在调试它时,我尝试比较curl与浏览器的Wireshark捕获(节点不支持SSLKEYLOGFILE, 强迫你跳过障碍,所以我什至没有尝试检查它的捕获看起来如何 https://github.com/nodejs/node/issues/2363#issuecomment-495929228)。存在如此多的细微差异,尝试对 Cloudflare 使用的规则进行逆向工程将非常耗时。--cert-status是一个幸运的猜测。

The SSL Client Hello across Firefox/curl/node are very different: Firefox firefox 70 curl curl --cert-status node11 node 11

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

HttpRequest 和 XMLHttpRequest 之间的真正区别 的相关文章

  • 暂停除了已激活的玩家之外的所有其他玩家。

    我有这个插件 它可以将不同的样式应用于 html5
  • 如何使用 JavaScript 创建链接?

    我有一个标题字符串和一个链接字符串 我不知道如何将两者放在一起以使用 JavaScript 在页面上创建链接 任何帮助表示赞赏 我试图解决这个问题的原因是因为我有一个 RSS 源并且有一个标题和 URL 列表 我想将标题链接到 URL 以使
  • Chart.js 在初始化时设置活动段

    我正在使用 Chart js v2 并且尝试在加载图表时模拟圆环图上某个段的 悬停状态 因此看起来有一个部分已突出显示 我已经搜索和梳理了代码一天 但找不到一个好的方法来做到这一点 提前致谢 设置片段的悬停样式有点令人困惑 因为它没有真正记
  • 渲染货币和符号并与来自不同单元格的数据相结合

    我正在使用最新的 jQuery DataTables v1 10 7 我正在尝试将数字解析为以下格式 239 90 USD 我可以使用此命令使货币正常工作 columns data Price render fn dataTable ren
  • Javascript Promise“then”始终运行,即使 Promise 未能执行

    我希望当调用第二个 then 时不执行第三个 then 但是 即使 Promise 被拒绝 调用第二个 then 并且代码返回 rejected 然后返回 undefined 它仍然调用第三个 then 如何不运行第三个 then 这样 未
  • 为什么 iife 在一个简单的例子中不起作用?

    我不明白为什么函数表达式调用不起作用并抛出错误 你能给我解释一下吗 var a function x alert x function a 1 谢谢大家 任务比我想象的要容易得多 这是因为 JS 将 IIFE 解析为函数的参数调用 这样做时
  • Chrome 中的性能问题

    我目前正在从事一个相对较大的项目 使用 AngularJs 构建 应用程序的一部分是一个表单 您可以向其中添加任意数量的页面 不幸的是 添加了很多不必要的垃圾 即表示表单模型的对象可能会变得非常大 在某些时候 Chrome 基本上无法处理它
  • 如何格式化 Highcharts 的 (x,y) 对数据的日期时间

    我的序列化方法会产生如下所示的日期时间字符串 2014 07 09T12 30 41Z 为什么下面的代码不起作用 function container highcharts xAxis type datetime series data x
  • 摩卡 - Chai Karma“套件未定义”

    我对 jscript tdd 很陌生 遇到了问题 希望有人能告诉我我在做什么 在浏览器中运行测试 通过 HTML 文件 一切正常 通过节点和业力运行它们我得到以下异常 我想在 node js 主机的 karma 中使用 Mocha 和 Ch
  • 带有淘汰赛js的隐形recaptcha

    我正在完成隐形验证码 但我在实现它时遇到问题 谷歌开发人员页面中的代码显示它应该是这样的
  • Snap.svg - 停止在可悬停元素的子元素上重新触发悬停事件

    对于一个项目 我使用的 SVG 形状由背景多边形和背景多边形上方的一些文本 我已将其转换为路径 组成 我正在使用 Snap svg 为我的形状设置动画 当我将鼠标悬停在多边形上时 形状应该缩放到特定尺寸 包括其中的所有内容 鼠标移开时 形状
  • React-Redux:state.setIn() 和 state.set() 有什么区别?

    我见过使用setIn and set 在一些react redux代码中 state setIn state set 我在这里找到了一些文档https facebook github io immutable js https facebo
  • 尝试将数据存储在点击器网站中

    我正在尝试存储一个名为的变量score无论何时刷新 您都会一次又一次地使用它 我不明白的是它的代码是什么 我尝试了一些方法 但似乎都不起作用 这是我的答题器网站 但是当我尝试使用 JavaScript 来存储它时 它不起作用window o
  • 如何解决 Typescript 构建中的错误“找不到模块 'jquery'”

    我目前在 ts 文件的顶部有这个import require jquery 我这样做是因为我试图在我的打字稿文件中使用 jquery 但我似乎无法编译它 因为它返回标题中所述的错误 我正在使用 ASP NET CORE 脚本文件夹 tsco
  • 为什么我们在打字稿中使用 HTMLInputElement ?

    我们为什么使用 document getElementById ipv as HTMLInputElement value 代替 document getElementById ipv value 功能getElementById返回具有类
  • DataTables row.add 到特定索引

    我正在替换这样的行项目 var targetRow entity row dataTable targetRow closest table dataTable DataTable dataTable row targetRow remov
  • 有没有办法在 onclick 触发时禁用 iPad/iPhone 上的闪烁/闪烁?

    所以我有一个有 onclick 事件的区域 在常规浏览器上单击时 它不会显示任何视觉变化 但在 iPad iPhone 上单击时 它会闪烁 闪烁 有什么办法可以阻止它在 iPad iPhone 上执行此操作吗 这是一个与我正在做的类似的示例
  • 可以设置标题样式吗? (并且使用CSS或js?)[重复]

    这个问题在这里已经有答案了 我想知道是否可以设计一个title a href title This is a title Hello a 样式问题有两个方面 文本格式 编码 我猜这是可能的 所以在问题中这样做 工具提示样式 你能把它弄大一点
  • Firebase 函数 onWrite 未被调用

    我正在尝试使用 Firebase 函数实现一个触发器 该触发器会复制数据库中的一些数据 我想观看所有添加的内容votes user vote 结构为 我尝试的代码是 const functions require firebase func
  • Javascript Replace() 和 $1 问题

    我正在尝试创建一个脚本来搜索文本中的模式并在它找到的字符串周围包裹一个标签 shop attributes td each function this html function i html return html replace E 0

随机推荐