Viv*_*ppo 5 javascript bash curl http node.js
所以我无意中发现了一些奇怪的东西,但不明白为什么会这样。
我在我的终端(iTerm 上是 ZSH)中创建了这个curl:
curl -I https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/find\?text\=1%20TX%2077979\&f\=json
Run Code Online (Sandbox Code Playgroud)
响应是:
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
Run Code Online (Sandbox Code Playgroud)
但是如果我在节点(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);
});
Run Code Online (Sandbox Code Playgroud)
响应如下所示:
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:
Run Code Online (Sandbox Code Playgroud)
谁能给我解释一下吗?
- - - 编辑 - - -
致安德鲁:我使用的网址包含“&”,但它们以“&query=”结尾,这不是强制性的,它仍然返回 HTTP 200 和其他需要的信息,这就是为什么我什至没有注意到。
正如@drew010 所写:
正如您所发现的,如果 URL 包含 & 字符,则需要引用该 URL,因为 shell 将其解释为控制运算符。如果 & 出现在命令或参数中的任何位置并且没有被引用或转义 & 我认为您会一直遇到同样的问题。
好的,根据文档(https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback)
传递给 exec 函数的命令字符串由 shell 直接处理,特殊字符(根据 shell 不同)需要进行相应处理:
因此,在以同样的方式执行“echo”之后,我发现 url 的末尾(“&f=json”)已被删除。
在 url 变量插值周围添加引号后,它工作正常。
exec(`curl -I "${url}"`, (err, std) =>
Run Code Online (Sandbox Code Playgroud)
我最初的困惑“为什么它应该做同样的事情时不同”也是我相信“exec”只会将它传递到我正在使用的终端的一部分,正如我之前提到的,它是带有 ZSH 的 iTerm,因为它是设置为我的操作系统上的默认终端。这个假设是错误的,文档中提到了这一点:
shell 用于执行命令的 Shell。请参阅 Shell 要求和默认 Windows shell。默认值:Unix 上的“/bin/sh”
所以它不使用默认的操作系统终端,而只是使用 sh。但可以通过“shell”选项使用您想要的任何内容。