问题
1. url.searchParams默认对参数编码;
let p = '123abc!*();:@&=+$,/?#[]-_.~ <>#%{}|\^`~'
let url = new URL()
url.searchParams.set('par',par)
url.search // p=123abc%21*%28%29%3B%3A%40%26%3D%2B%24%2C%2F%3F%23%5B%5D-_.%7E+%3C%3E%23%25%7B%7D%7C%5E%60%7E
2. vue-router也会默认对参数进行编码;
url = 'abc.com?a=123/456+!789'
fullPath = 'abc.com?a%3D123%2F456%2B!789'
export default context => {
const { url } = context;
const { fullPath } = router.resolve(url).route
}
3. url跳转query参数丢失;
module.exports = (ctx, url) => {
let queryStr = '';
const { query } = ctx;
const queryList = [];
Object.keys(query).forEach((item) => {
queryList.push(`${item}=${query[item]}`);
});
queryStr = `?${queryList.join('&')}`
}
example.com?target=encodeURIComponent(https://target.com…
这样重定向之后就只会存在a=1的参数;
结论:URL编码方式不同
Percent-encoding, also known as URL encodingURL 和 URLSearchParams 基于最新的 URL 规范:RFC3986,而 encode* 函数是基于过时的 RFC2396。它们之间有一些区别,例如对 IPv6 地址的编码方式不同:
RFC3986规定Url中只允许包含英文字母(a-zA-Z)、数字(0-9)、-_.~4个特殊字符以及所有保留字符
保留字符: ! * ' ( ) ; : @ & = + $ , / ? # [ ]
英文字母(a-zA-Z)、数字(0-9)、-_.* | ~[]<>%{} | ^` | 空格 | #$&, | + | :;=? | / | @ | !() | |
URLSearchParams | - | %7E%5B%5D%3C%3E%25%7B%7D%7C%5E%60 | + | %23%24%26%2C | %2B | %3A%3B%3D%3F | %2F | %40 | %21%28%29 | |
escape | - | %7E%5B%5D%3C%3E%25%7B%7D%7C%5E%60 | %20 | %23%24%26%2C | - | %3A%3B%3D%3F | - | - | %21%28%29 | |
encodeURIComponent | - | %7E%5B%5D%3C%3E%25%7B%7D%7C%5E%60 | %20 | %23%24%26%2C | %2B | - | - | - | !() | |
encodeURI | - | %7E%5B%5D%3C%3E%25%7B%7D%7C%5E%60 | %20 | #$&, | - | %3A%3B%3D%3F | %2F | %40 | !() |
URL常见使用Query的方式
-
JS的API:escape、encodeURIComponent 和 encodeURI
-
浏览器发出https请求
-
vue router的编码方式,调用浏览器的encodeURIComponent和decodeURIComponent;
let par = '123abc!*();:@&=+$,/?#[]-_.~ <>#%{}|\^`~'
1. URLSearchParams
! () ; : @ & = + $ , / ? # [ ] ~ < > % { } | \ ^ ` ~ 被转码
*-_. 未被转码
let url = new URLSearchParams()
url.set('par',par)
url.toString();
// par=123abc%21*%28%29%3B%3A%40%26%3D%2B%24%2C%2F%3F%23%5B%5D-_.%7E+%3C%3E%23%25%7B%7D%7C%5E%60%7E
url.get('par')
// '123abc!*();:@&=+$,/?#[]-_.~ <>#%{}|^`~'
URLSearchParams的set/append都会进行编码,get其实会进行解码;
但是URL的search会返回当前toString()的内容
url.spec.whatwg.org/#urlsearchp…
urlSearchParams的编码方式:
-
编码字符串:escape [] <>%{}|^` #$&, !();: =?~~ 被转码
-
编码URL的参数:encodeURIComponent [] <>%{}|^` #$&+, /:;=?@ 被转码
-
编码整个URL:encodeURI [] <>%{}|^` 被转码。
escape(par)
// '123abc%21*%28%29%3B%3A@%26%3D+%24%2C/%3F%23%5B%5D-_.%7E%20%3C%3E%23%25%7B%7D%7C%5E%60%7E'
encodeURIComponent(par)
// '123abc!*()%3B%3A%40%26%3D%2B%24%2C%2F%3F%23%5B%5D-_.~%20%3C%3E%23%25%7B%7D%7C%5E%60~'
encodeURI(par)
// '123abc!*();:@&=+$,/?#%5B%5D-_.~%20%3C%3E#%25%7B%7D%7C%5E%60~'
encodeURI和encodeURIComponent的区别:
一个自然的问题:“encodeURIComponent 和 encodeURI 之间有什么区别?我们什么时候应该使用哪个?”如果我们看一个 URL,就容易理解了,它被分解为本文上面图中所示的组件形式:site.com:8080/path/page?p…正如我们所看到的,在 URL 中 :,?,=,&,# 这类字符是被允许的。……另一方面,对于 URL 的单个组件,例如一个搜索参数,则必须对这些字符进行编码,以免破坏 URL 的格式。encodeURI 仅编码 URL 中完全禁止的字符。encodeURIComponent 也编码这类字符,此外,还编码 #,$,&,+,,,/,:,;,=,? 和 @ 字符。所以,对于一个 URL 整体aa,我们可以使用 encodeURI:而对于 URL 参数,我们应该改用 encodeURIComponent:
浏览器发出请求:
window.location.href 自动encode: 空格、`、<>