• 谈一谈URL


    作者:ManfredHu
    链接:http://www.manfredhu.com/2017/08/16/22-url/index.html
    声明:版权所有,转载请保留本段信息,谢谢大家

    URLURL

    URL

    普及篇,作为互联网从业者如果连链接都不认识,很难交流。不知道你们有没有遇到这样的情况,开发要给产品一个链接叫产品体验,开发说打开链接加个_test=1的参数,产品说,怎么搞啊,我不会呀!!!我不会呀!!!我不会呀!!!所以要普及一些网络姿势!!

    URL的由来

    我们的身份证有18个号码,标识了我们的唯一。

    URL全称Uniform Resource Locator 统一资源定位符(或称统一资源定位器/定位地址、URL地址等,常缩写为URL),有时也被俗称为网页地址(网址)。如同在网络上的门牌,是因特网上标准的资源的地址(Address)。它最初是由蒂姆·伯纳斯-李发明用来作为万维网的地址。现在它已经被万维网联盟编制为因特网标准RFC 1738。

    URL的组成部分

    URL的协议类型:

    举个栗子,如下URL:

    http://www.tmtpost.com/2737087.html?mobile=1&mdebug=1#haha=init&lh=1

    标识了一个互联网上的文件的地址。

    在控制台输入window.location 会输出信息,大概如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Location
    hash:"#haha=init&lh=1"
    host:"www.tmtpost.com"
    hostname:"www.tmtpost.com"
    href:"http://www.tmtpost.com/2737087.html?mobile=1&mdebug=1#haha=init&lh=1&test=1"
    origin:"http://www.tmtpost.com"
    pathname:"/2737087.html"
    port:""
    protocol:"http:"
    search:"?mobile=1&mdebug=1"
    格式部分例子对应的部分获取代码
    protocol http: window.location.protocol
    host //www.tmtpost.com window.location.host
    port http默认为80,https默认为443,本例为空 window.location.port
    pathname /2737087.html window.location.pathname
    search ?mobile=1&mdebug=1 window.location.search
    hash #haha=init&lh=1 window.location.hash

    window.location.href 和 window.location.replace

    • window.location.href 是一个可读可写的属性。读则返回整个URI字符串,写则跳转页面。
    • window.location.replace 是一个方法,同样用于页面跳转,只是同时会把历史纪录替换掉,所以你后退回不去原来的链接,而 window.location.href 是有记录的。

    注意:这里只可以跳转到同个host下的不同pathname。

    1
    2
    3
    4
    5
    //如果你打开www.baidu.com在控制台输入
    window.location.href = "www.qq.com";
    //则url会变成 https://www.baidu.com/www.qq.com
    //百度会告诉你它根本不认识这货而跳转到错误搜索
    //测试环境为Chrome

    构建URL

    业务中经常会用URL的参数,通常是 location.search 这里的部分来做一些业务相关的操作,比如某些功能的体验,加了一个参数就可以打开体验等等。这里通常就是操作

    http://www.tmtpost.com/2737087.html?mobile=1&mdebug=1#haha=init&lh=1

    这样链接的 ?mobile=1&mdebug=1部分,通过添加其他参数来构成URL.
    比如我们上面情景下的开发哥哥想要你加上_test=1

    那么就会形成 ?mobile=1&mdebug=1&_test=1的search部分。
    这里参数以&符号来分割。

    总的链接为

    http://www.tmtpost.com/2737087.html?mobile=1&mdebug=1&_test=1#haha=init&lh=1

    这就是开发哥哥想要的URL了。

    HASH的读写

    location.hash为获取的hash,通常的单页SPA下会通过hash的变化来判断执行的模块方法。这块通常也是一些基础面试里面会问到的题目,让你现场写一个东西来获取URL里面的参数,因为场景太常用了,所以是必修题。记得在大三去微信TIT面试的时候有一道就是这样的,考察的是JS正则表达式的使用和对URL的理解是否深刻。

    hash的常见类型如: #haha=init&lh=1&test=1

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    var URL = {};
    URL.setHash = function(hash){
    location.hash = hash;
    }
    URL.getHash = function(){
    var hash = location.hash;
    return hash ? hash.replace(/.*#/,""):""; //删除掉#前面(包括#)的所有字符
    }
    URL.getHashParam = function(key){
    var hash = URL.getHash();
    //这里会取到haha=init&lh=1这样的字符串,用正则来捕获key为传入key的值
    var result = hash.match(new RegExp("(^|&)"+ key +"=([^&]*)(&|$)"));
    return result != null ? result[2]: "";
    }

    SEARCH部分

    location.search部分为?号 后面的内容,跟HASH类似,也是key=value的模式。

    search的常见类型如: ?mobile=1&mdebug=1&_test=1

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    var URL = {};
     
    //HASH部分
    URL.setHash = function(hash){
    location.hash = hash;
    }
    URL.getHash = function(){
    var hash = location.hash;
    return hash ? hash.replace(/.*#/,""):""; //删除掉#前面(包括#)的所有字符
    }
    URL.getHashParam = function(key){
    var hash = URL.getHash();
    //这里会取到haha=init&lh=1这样的字符串,用正则来捕获key为传入key的值
    var result = hash.match(new RegExp("(^|&)"+ key +"=([^&]*)(&|$)"));
    return result != null ? result[2]: "";
    }
     
    //SEARCH部分
    URL.getSearch = function(){
    var search = location.search; //得到形如 ?mobile=1&mdebug=1 这样的字符串
    return search ? search.replace(/.*?/,""):""; //删除掉?前面(包括?)的所有字符
    }
    //支持传入url
    URL.getSearchParam = function(key,url){
    var search = url ? url :URL.getSearch();
    //这里会取到haha=init&lh=1这样的字符串,用正则来捕获key为传入key的值
    var result = search.match(new RegExp("(^|&)"+ key +"=([^&]*)(&|$)"));
    return result != null ? result[2]: "";
    }

    URL编码解码

    window全局对象下有几个方法函数是对URL进行处理的。有这些

    • window.decodeURI
    • window.encodeURI
    • window.decodeURIComponent
    • window.encodeURIComponent
    • window.unescape
    • window.escape

    很明显,这是三对类似的情侣。相爱相杀,一个用来解码一个用来编码。

    首先,我们看一下阮一疯的关于URL编码这里先入个门再来看我们下面的总结部分。

    废弃的escape和unescape

    这一对可以对中文进行编解码操作,以前用的比较多,现在已经不提倡使用(废弃)看下面的例子:

    1
    2
    3
    4
    escape("醉了")
    //"%u9189%u4E86"
    unescape("%u9189%u4E86")
    //"醉了"

    同理我们可以对比String.charCodeAt方法,这个方法会返回字符串某个字符的unicode编码。

    escape和String.charCodeAt方法的联系

    1
    2
    3
    4
    "醉了".charCodeAt(0) //37257(十进制)
    "醉了".charCodeAt(1) //20102(十进制)
    parseInt(escape("醉").match(/d+/)[0],16) //37257(十进制)
    parseInt(escape("了").match(/d+/)[0],16) //20102(十进制)

    这里我们用escape编码 字得到字符的unicode编码"%u9189",然后用String.match匹配整数部分得到16进制的9189,然后用parseInt方法将9189转码为十进制得到与charCodeAt方法一样的数字——37257

    encodeURI和decodeURI

    这一对会对一些符号进行编码(如空格转为%20),其他一些在网址中有特殊含义的符号”; / ? : @ & = + $ , #”,不进行编码。编码后,它输出符号的utf-8形式,并且在每个字节前加上%。

    1
    2
    3
    4
    5
    6
    encodeURI("醉了")
    //"%E9%86%89%E4%BA%86"
    encodeURI("醉了 ")
    //"%E9%86%89%E4%BA%86%20"
    decodeURI("%E9%86%89%E4%BA%86%20")
    //"醉了 "

    encodeURIComponent和decodeURIComponent

    与encodeURI()的区别是,它用于对URL的组成部分进行个别编码,而不用于对整个URL进行编码。

    因此,”; / ? : @ & = + $ , #”,这些在encodeURI()中不被编码的符号,在encodeURIComponent()中统统会被编码

    1
    2
    3
    4
    encodeURI('哈哈hao123;/?:@&=+$,#')
    "%E5%93%88%E5%93%88hao123;/?:@&=+$,#"
    encodeURIComponent('哈哈hao123;/?:@&=+$,#')
    "%E5%93%88%E5%93%88hao123%3B%2F%3F%3A%40%26%3D%2B%24%2C%23"

    escape和encodeURIComponent的区别

    上例说了encodeURI和encodeURIComponent的区别,区别不大.只是在; / ? : @ & = + $ , #这些特殊符号编不编码的问题.
    而escape和encodeURI的区别则是——Unicode编码和UTF-8的区别.

    因为escape会将传入的字符串参数转码为Unicode,而encodeURI则会将传入的字符串参数转码为可以直接在互联网传递的UTF-8格式.

    Unicode和UTf-8

    UTF-8

    UTF-8是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。

    UTF-8的编码规则很简单,只有二条:

    1. 对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。
    2. 对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。

    对照关系如下:

    Unicode符号范围(十六进制)UTF-8编码方式(二进制)
    0000 0000-0000 007F 0xxxxxxx
    0000 0080-0000 07FF 110xxxxx 10xxxxxx
    0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
    0001 0000-0010 FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

    Unicode和UTF-8的转化

    以醉了的醉字为例

    1
    2
    3
    4
    "醉".charCodeAt(0)
    //37257(十进制)
    encodeURI('醉')
    //"%E9%86%89"

    可以这里醉字的UTF-8编码为三字节,E9 86 89
    转化为二进制为 11101001 10000011 10001001
    对应上面表格的第三行,将其代入第三行的UTF-8编码的部分,得到替代的x部分为1001 000011 001001则为醉字的Unicode编码部分.

    1
    2
    3
    4
    5
    6
    parseInt('1001 000011 001001'.replace(/s/g,''),2)
    //37065
    "醉".charCodeAt(0)
    //37257(十进制)
    parseInt(escape('醉').match(/d+/)[0],16)
    //37257(十进制)
  • 相关阅读:
    Linxu 挂载光盘和硬盘
    Linux firewall
    指纹获取 Fingerprint2
    Vue 封装的组件生命周期钩子
    vue富文本编辑,编辑自动预览,单个图片上传不能预览的问题解决:
    vue 集成百度富文本编辑器
    axios 的二次封装
    element 列表中已选的标记
    element 表单的input循环生成,并可单个input失去焦点单个验证并保存; (多个表单实例)
    axios 二进制流导出
  • 原文地址:https://www.cnblogs.com/manfredHu/p/7366094.html
Copyright © 2020-2023  润新知