【问题标题】:Curl - different result in node (child process) and terminalCurl - 节点(子进程)和终端中的不同结果
【发布时间】:2021-03-05 21:22:06
【问题描述】:

所以我不小心发现了一些奇怪的东西,不知道为什么。

我在我的终端(即 iTerm 上的 ZSH)中制作了这个 curl:

curl -I https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/find\?text\=1%20TX%2077979\&f\=json

响应是:

HTTP/2 200
date: Wed, 28 Oct 2020 17:31:12 GMT
content-type: application/json;charset=UTF-8
content-length: 374
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
server:
etag: dc0a3f17
x-esri-ftiles-cache-compress: true
cache-control: max-age=300
x-cached: MISS
vary: Origin,Accept-Encoding
strict-transport-security: max-age=31536000

但是如果我像这样在节点(v14.14.0)中运行与 exec child_process 相同的 curl:

const { exec } = require('child_process');
const url = 'https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/find\?text\=1%20TX%2077979\&f\=json';

return exec(`curl -I ${url}`, (err, std) => {
  console.log(std);
});

响应如下所示:

HTTP/2 403 
date: Wed, 28 Oct 2020 17:17:18 GMT
content-type: text/html;charset=utf-8
content-length: 680
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
server: 

谁能给我解释一下?

----- 编辑-----

致安德鲁: 我使用的 url 包含 '&' 但它们以 '&query=' 结尾,这不是强制性的,它仍然返回 HTTP 200 和其他需要的信息,这就是我什至没有注意到的原因。

【问题讨论】:

  • 如您所见,如果 URL 包含 & 字符,则需要引用 URL,因为这将被 shell 解释为控制运算符。您是否有任何带有 & 的示例 URL 没有这样做?如果& 出现在您的命令或参数中的任何位置并且没有被引用或转义\& 我认为您会一直遇到同样的问题。
  • @drew010 你是对的。我有包含 '&' 的 url,但它们以 '&query=' 结尾,这不是强制性的,它仍然返回 HTTP 200 和其他需要的信息,这就是我什至没有注意到的原因。谢谢。
  • 有道理!有时 & 不会使命令完全失败,并且会使追查问题变得更加困难,例如 URL 的一部分被截断但在一定程度上仍然有效。

标签: javascript node.js bash http curl


【解决方案1】:

正如@drew010 所写:

如您所见,如果 URL 包含 & 字符,则需要引用它 因为这将被 shell 解释为控制操作符。如果 & 出现在您的命令或参数中的任何位置,并且没有被引用或 逃脱了,我想你会一直遇到同样的问题。

好的,根据文档 (https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback)

直接处理传递给exec函数的命令字符串 由外壳和特殊字符(因外壳而异)需要 相应处理:

所以在执行 'echo' 后,我发现 url 的结尾 ("&f=json") 正在被删除。

在 url 变量插值周围添加引号后,它工作正常。

exec(`curl -I "${url}"`, (err, std) =>

我最初的困惑“为什么它应该做同样的事情时会有所不同”也是我相信'exec'只会将它传递给我正在使用的终端的一部分,因为我前面提到的是带有 ZSH 的 iTerm,因为它在我的操作系统上被设置为默认终端。该假设是错误的,文档中提到了它:

shell 用来执行命令的shell。请参阅壳牌要求和 默认的 Windows 外壳。默认值:Unix 上的“/bin/sh”

所以它没有使用默认的 OS 终端,而只是 sh。 但是可以使用任何你想要的 'shell' 选项。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-05
    • 2021-07-26
    • 2014-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-19
    • 2018-06-19
    相关资源
    最近更新 更多