Javascript 中的神秘字符串行为
Mysterious string behavior in Javascript
let host = req.headers.host
console.log(host)
打印 localhost:3000
。到目前为止一切顺利。
console.log(host === "localhost:3000")
打印 false
。嗯?
console.log(host.length)
console.log("localhost:3000".length)
打印 15
和 14
。我们的神秘字符串长了一个字符?让我们一个一个地看每个角色。
for (var i = 0; i < host.length; i++) {
console.log(i, host.charAt(i));
}
打印:
0 l
1 o
2 c
3 a
4 l
5 h
6 o
7 s
8 t
9 :
10 6
11 0
12 6
13 4
14 3
一次打印一个字符显示冒号后现在有 5 个数字:60643
。 什么?
每次我重新启动我的网络服务器时,这个结果都会改变。例如,上一个 运行 是 63275
而前一个 运行 是 54313
.
在 for 循环确认后立即添加 console.log(host)
字符串仍然是 localhost:3000
。这是怎么回事?
我几乎觉得问这个问题很疯狂,但我已经看了一整天,这种情况 100% 都会发生。环境:最新版本的 Node (v17.3.0
), macOS Monterey (M1 mac).
跟进
- Reproducible example here (requires a free Vercel 帐号)
typeof host
returns string
- 这里是每个字符的附加调试信息
字符串:
i
charAt(i)
charCodeAt(i)
codePointAt(i).toString(16)
0
l
108
6c
1
o
111
6f
2
c
99
63
3
a
97
61
4
l
108
6c
5
h
104
68
6
o
111
6f
7
s
115
73
8
t
116
74
9
:
58
3a
10
5
53
35
11
4
52
34
12
8
56
38
13
6
54
36
14
2
50
32
根据 documentation:
The vercel dev command is used to replicate the Vercel deployment
environment locally, allowing you to test your Serverless Functions,
without requiring you to deploy each time a change is made.
因此,像 /api/hello
这样的调用由本地代理服务器 运行 随机空闲端口处理。
这里最interesting thing begins:对于代理服务器的标准输出(stdout)(当然console.log
也是如此),代理端口被替换为开发端口(感觉像是过时的遗产):
p.stdout.on('data', (data: string) => {
process.stdout.write(data.replace(proxyPort, devPort));
});
因此,req.headers.host
和localhost:3000
的长度是有区别的,为什么在console.log
中看起来一样,但比较起来却不相等.
所以最好使用 x-forwarded-host
header 而不是 host
:
console.log((
req.headers['x-forwarded-host'] || req.headers.host
) === "localhost:3000");
res.status(200).json(req.headers);
let host = req.headers.host
console.log(host)
打印 localhost:3000
。到目前为止一切顺利。
console.log(host === "localhost:3000")
打印 false
。嗯?
console.log(host.length)
console.log("localhost:3000".length)
打印 15
和 14
。我们的神秘字符串长了一个字符?让我们一个一个地看每个角色。
for (var i = 0; i < host.length; i++) {
console.log(i, host.charAt(i));
}
打印:
0 l
1 o
2 c
3 a
4 l
5 h
6 o
7 s
8 t
9 :
10 6
11 0
12 6
13 4
14 3
一次打印一个字符显示冒号后现在有 5 个数字:60643
。 什么?
每次我重新启动我的网络服务器时,这个结果都会改变。例如,上一个 运行 是 63275
而前一个 运行 是 54313
.
在 for 循环确认后立即添加 console.log(host)
字符串仍然是 localhost:3000
。这是怎么回事?
我几乎觉得问这个问题很疯狂,但我已经看了一整天,这种情况 100% 都会发生。环境:最新版本的 Node (v17.3.0
), macOS Monterey (M1 mac).
跟进
- Reproducible example here (requires a free Vercel 帐号)
typeof host
returnsstring
- 这里是每个字符的附加调试信息 字符串:
i |
charAt(i) |
charCodeAt(i) |
codePointAt(i).toString(16) |
---|---|---|---|
0 | l | 108 | 6c |
1 | o | 111 | 6f |
2 | c | 99 | 63 |
3 | a | 97 | 61 |
4 | l | 108 | 6c |
5 | h | 104 | 68 |
6 | o | 111 | 6f |
7 | s | 115 | 73 |
8 | t | 116 | 74 |
9 | : | 58 | 3a |
10 | 5 | 53 | 35 |
11 | 4 | 52 | 34 |
12 | 8 | 56 | 38 |
13 | 6 | 54 | 36 |
14 | 2 | 50 | 32 |
根据 documentation:
The vercel dev command is used to replicate the Vercel deployment environment locally, allowing you to test your Serverless Functions, without requiring you to deploy each time a change is made.
因此,像 /api/hello
这样的调用由本地代理服务器 运行 随机空闲端口处理。
这里最interesting thing begins:对于代理服务器的标准输出(stdout)(当然console.log
也是如此),代理端口被替换为开发端口(感觉像是过时的遗产):
p.stdout.on('data', (data: string) => {
process.stdout.write(data.replace(proxyPort, devPort));
});
因此,req.headers.host
和localhost:3000
的长度是有区别的,为什么在console.log
中看起来一样,但比较起来却不相等.
所以最好使用 x-forwarded-host
header 而不是 host
:
console.log((
req.headers['x-forwarded-host'] || req.headers.host
) === "localhost:3000");
res.status(200).json(req.headers);