最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 你必须知道的 URI

    正文概述 掘金(布纳纳大草莓)   2021-01-21   504

    什么是 URIURIURL 的区别是? URI 的编码方法?

    如果不知道的话就往下看看吧~

    什么是 URI

    URIUniform Resource Identifier),也就是 统一资源标识符

    它的 作用 就是区分互联网上不同的资源。

    URI 包括两个部分:

    • URL (Uniform Resource Location)统一资源定位符
    • URN (Uniform Resource Name)统一资源名称

    URI结构

    scheme :// user:passwd @ host:port path ? query #fragment

    scheme 表示协议名,比如 http , https , file 等等。后面必须和 ://连在一起。协议可以自定义。

    user:passwd@ 表示登陆主机时的用户名和密码,不过很不安全,不推荐使用,也不常用。

    host:port 表示主机名和端口。

    path 表示请求路径,标记资源所在位置。

    query 表示查询参数 ,以? 开始,为 key = val 键值对的形式 ,以 & 隔开。

    fragment 也叫哈希。表示 URI 所定位的资源内的一个锚点,浏览器可以根据这个锚点跳转到对应位置。

    例子:

    https://www.baidu.com/s?wd=HTTP&rsv_spt=1#heading-8
    

    httpsscheme 协议

    www.baidu.comhost:port 主机名和端口。注意,httphttps 的默认端口分别是80、443。

    /spath 请求路径,标记资源所在位置。

    wd=HTTP&rsv_spt=1query 参数部分,且为两个。

    heading-8fragment 锚点。

    URLhttps://www.baidu.com/s?wd=HTTP&rsv_spt=1

    URNwww.baidu.com/s?wd=HTTP&rsv_spt=1#heading-8

    URI 编码方法

    URI 只能使用ASCII, ASCII 之外的字符是不支持显示的,而且还有一部分符号是界定符,如果不加以处理就会导致解析出错。

    因此,URI 引入了 编码机制 ,将所有非 ASCII 码字符界定符转为十六进制字节值,然后在前面加个%

    如,空格被转义成了%20,布纳纳被转义成了 %E5%B8%83%E7%BA%B3%E7%BA%B3

    encodeURI()encodeURIComponent()

    encodeURI()encodeURIComponent() 方法用于编码统一资源标识符(URI),以便传给浏览器。

    • encodeURI()方法用于对整个 URI 进行编码
    • encodeURIComponent() 方法用于编码 URI 中单独的组件,
    let uri = "https://zhuanlan.zhihu.com/p/40311981?redirect=a"
    
    console.log(encodeURI(uri))
    // https://zhuanlan.zhihu.com/p/40311981?redirect=a
    // 使用 encodeURI()编码后,除空格被替换为%20 之外,没有任何变化。
    
    console.log(encodeURIComponent(uri))
    // https%3A%2F%2Fzhuanlan.zhihu.com%2Fp%2F40311981%3Fredirect%3Da
    // encodeURIComponent()方法将所有非字母字符都替换成了相应的编码形式。
    

    因此,我们发现这两个方法的 主要区别 是:encodeURI() 不会编码属于 URL 组件的特殊字符,比如冒号、斜杠、问号、 井号,而 encodeURIComponent() 会编码它发现的所有非标准字符。这就是使用 encodeURI() 编码整个 URI,但只使用 encodeURIComponent() 编码那些会追加到已有 URI 后面的字符串的原因。

    注意 一般来说,使用 encodeURIComponent() 比使用 encodeURI() 的频率更高, 这是因为编码查询字符串参数比编码基准 URI 的次数更多。

    decodeURI()decodeURIComponent()

    • decodeURI() 只对使用 encodeURI() 编码过的 字符解码。

    • 同样,decodeURIComponent() 只对使用 encodeURIComponent() 编码过的字符解码 ,基本上就是解码所有特殊值。

    例子:

    let uri = "http%3A%2F%2Fwww.wrox.com%2Fillegal%20value.js%23start";
    
    console.log(decodeURI(uri));
    // http%3A%2F%2Fwww.wrox.com%2Fillegal value.js%23start
    
    console.log(decodeURIComponent(uri)); 
    // http:// www.wrox.com/illegal value.js#start
    

    这里,uri 变量中包含一个使用 encodeURIComponent()编码过的字符串。

    首先输出的是使用 decodeURI() 解码的结果,可以看到只用空格替换了%20

    然后是使用 decodeURIComponent() 解码的 结果,其中替换了所有特殊字符,并输出了没有包含任何转义的字符串。(这个字符串不是有效的 URL。

    如何获取 URI 参数?

    // 1.取 ? 开头,# 结尾 的字符串
    // 2.根据 & 分割参数
    // 3.根据 = 分割键值对
    
    function getParams(str){
      // ? 的索引
      const startIdx = str.indexOf('?') + 1;
      const endIdx = str.indexOf('#')
      const paramString = str.substring(startIdx ,endIdx);
      console.log('paramString:' + paramString)
      
      const kvArr = paramString.split('&');
      console.log('kvArr:' + kvArr)
      
      const params = {};
      
      kvArr.forEach(item =>{
        const [k,v] = item.split('=');
        params[k] = v;
      });
      return params;
    }
    
    console.log(getParams('https://zhuanlan.zhihu.com/p/40311981?redirect=a&param=b#heading-8'));
    

    https://zhuanlan.zhihu.com/p/40311981?redirect=https://www.baidu.com?a=10&param=b#heading-8 的参数是?

    console.log(getParams('https://zhuanlan.zhihu.com/p/40311981?redirect=https://www.baidu.com?a=10&param=b#heading-8'));
    
    // {redirect: "https://www.baidu.com?a", param: "b"}
    

    这明显不对, redirect 的值应该是 https://www.baidu.com?a=10 。解决:

    let redirect = "https://www.baidu.com?a"
    let uri = `https://zhuanlan.zhihu.com/p/40311981?redirect=${encodeURIComponent(redirect)}&param=b#heading-8`
    
    console.log(getParams(uri))
    

    如果想让参数只有 redirect 且值是 https://www.baidu.com?a=10&param=b呢?

    let redirect1 = "https://www.baidu.com?a=10&param=b"
    let uri1 = `https://zhuanlan.zhihu.com/p/40311981?redirect=${encodeURIComponent(redirect1)}#heading-8`
    
    console.log(getParams(uri1))
    

    最后

    如有问题请大佬指正~

    如有帮助,希望能够点赞收藏~

    参考资料:

    • JavaScript高级程序设计(第4版)
    • 维基百科的统一资源标志符
    • (建议精读)HTTP灵魂之问,巩固你的 HTTP 知识体系

    起源地下载网 » 你必须知道的 URI

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元