url 中 ? 号后面一般跟的是请求参数,用来给后台传参,# 号后面跟的是 hash,和标签的 id 配合,用来定位页面,那么当一个 url 既要有 ? 号,又要有 # 号时,它们的位置关系应当如何,是 # 号必须在 ? 号前面,还是 ? 号必须在 # 号前面,还是无所谓。
当 url 存在 ? 和 # 号时,# 号是放在 ? 号后面的,通过下面测试代码说明:
html 代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>url 中 # 号与 ? 号的位置关系</title>
<style>
#box1, #box2 {
width: 100px;
height: 1000px;
background: red;
}
#box2 {
background: green;
}
</style>
</head>
<body>
<div id="box1"></div>
<div id="box2"></div>
</body>
</html>
node 代码:
const http = require('http');
const url = require('url');
const fs = require('fs');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
console.log('req.url: ', url.parse(req.url));
fs.readFile('test.html', 'utf8' , (err, data) => {
if (err) {
console.error(err);
res.statusCode = 500;
res.end('');
return;
}
res.statusCode = 200
res.setHeader('Content-Type', 'text/html')
res.end(data);
})
});
server.listen(port, hostname, () => {
console.log(`服务器运行在 http://${hostname}:${port}/`)
});
当请求路径为:http://127.0.0.1:3000/?a=1#box2 时,页面是能定位到 box2 的,同时 node 那边的打印如下:
可以看出,node 端是可以解析出请求参数的,hash 应该为 #box2,但是打印出来时 null,有点奇怪,后面有空看下。
当请求路径为:http://127.0.0.1:3000/#box2?a=1 时,页面不能定位到 box2,同时 node 那边的打印如下:
可以看出,node 端不能解析出请求参数。
通过以上测试,不管是对于前端还是后台,url 中如果同时出现 # 和 ?,# 应该在 ? 号的后面。
这是为什么呢?
对于请求参数,我们一般会用 encodeURIComponent 函数进行转码,encodeURIComponent 函数也会对 # 号进行转码,也就是 ? 号后面如果出现了 # 号,那么 # 号一定不是请求参数的一部分,而是 hash 定位,浏览器应该是这样认为的。如果 # 号在 ? 号前面,当遇到 ? 号时,怎么判断 ? 号是 hash 的一部分,还是请求参数的开始,是无法判断的,标签的 id 的值,又没说,id 中不能出现 ? 号。
综上,url 中出现 # 和 ? 号时,# 号要在 ? 号后面。