Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

URL再理解 #18

Open
2 tasks
LiberoWang opened this issue Nov 20, 2017 · 0 comments
Open
2 tasks

URL再理解 #18

LiberoWang opened this issue Nov 20, 2017 · 0 comments

Comments

@LiberoWang
Copy link

LiberoWang commented Nov 20, 2017

题目:
小明刚开始学习前端编程,发现一个术语经常出现:URL.他大概知道URL是个什么样的概念,但是不知道哪些URL是合法的,哪些是不合法的?究竟一个完整的url由哪些部分构成呢?
请阅读URL规范文档,告诉小明答案。
任务:
调查URL

1.URL的构成

scheme://[user:password@]hostname[:port]/path/[;parameters][?query][#fragment]

scheme: 协议名(不区分大小写),以冒号(:)结束。协议所表示的是获取该资源需要使用的协议。一般协议有http、https、ftp、gopher、telnet、file等。
//:层级URL标识符号。基本上每个URL中都会包含这个符号,是固定的;可以理解为把协议与后面的信息进行分隔开的一个符号。这样的一个好处是Web应用无需关注某个协议的具体实现,而只需要关注于’//’符号后面的指向地址即可。
但是也存在这非层级结构的URL:例如,mailto:协议。当使用mailto:[email protected]?....的时候,该URL将能够传递到默认的邮件客户端程序而无需其他的解析。
user:password@:授权信息/身份验证, @前的是密码:冒号前的是用户名,该部分使用的是@作为该部分的结束符号。很多服务器都要求输入用户名和密码才会允许用户访问数据。其实这一块信息我们看到的比较少,这是一个可选部分,一般的协议(http\https之类)都会使用默认的匿名形式进行数据获取。FTP服务器就是一个常见的实例。

ftp://[email protected]/pub/gnu
ftp://anonymous:[email protected]/pub/gnu
http://joe:[email protected]/sales_info.txt

如果某应用程序使用的URL方案要求输入用户名和密码,比如FTP,但是用户没有提供,通常会插入一个默认的用户名和密码(FTP URL,没有指定用户名和密码,会以anonymous(匿名用户)作为用户名,IE会以IEUser作为密码)。
hostname:服务器地址。这是一个很关键的部分,这关系到你需要从哪个服务器上去获取资源。而我们看到的比较多的是这部分以域名(htc.org)的形式呈现,还有以Ipv4(220.181.111.188)的地址呈现。当然也能够以Ipv6的形式呈现。按照标准的描述是这部分只能用:数字、“.”、“-”组成。但浏览器对这支持的字符会比较多。
port: 服务器端口。这里是属于网络端口,因此可选为[0~2^16),这里的端口并不是物理端口,而是逻辑端口;只要是为了处理多进程时数据进行传输的时候,保证各进程中数据不会发生紊乱,能够传送到相应的进程中所设定的。
path:前面提到的URL指向的是一个唯一确定的资源,而这里指向的是资源的完整路径(即存储的位置,在服务器的哪个地方),一般都是用 / 进行分层描述。
parameters:参数。有些方案,单靠主机名和路径是不足的,需要更多的信息才能工作。负责解析URL的应用程序需要这些协议参数来访问资源。否则服务器不提供服务或者提供错误服务。
ftp://prep.ai.mit.edu/pub/gnu;type=d
有一个参数type=d,参数名type,值为d。
http://www.joes-hardware.com/hammers;sale=false/index.html;graphics=true
有俩个路径段,hammers和index.html。hammers段有参数sale值为false,index.html有参数graphisc值为true。
?query:查询字符串。用“&”符号隔开,每个参数的名和值用“=”对应。这里的查询字符串是用于参数传递给服务器端。但标准没有对这一部分有着特别严格的规定。这一部分是以 ? 开始作为标识,而现在一般的用法都是类似于以下的形式,?name=hello&id=5&…
#fragment:该部分与上面的?后面的表单信息本质的区别就是这部分内容不会被传递到服务器端。一般用于页面的锚。就是我们常见的网站右下脚一般有一个回到顶部的按钮,一般就是使用其实现的。

2.URL解析

url-analysis

解析url

  • 判断URL是否是合法的URL,如果URL不合法,则调用默认的搜索引擎,直接把输入的内容作为要搜索的内容进行搜索,如果URL合法,则继续下一步。
  • 检查这些请求是HTTPS还是HTTP,如果是HTTPS的话则使用HTTPS协议进行访问,否则使用HTTP协议发送。有些情况下,第一个请求不是HTTPS的,但是当浏览器向网站发出第一个HTTP请求之后,网站会返回浏览器一个响应,请求浏览器使用HTTPS发送请求。
  • 将URL进行字符转换

查找IP地址

  • 先检查浏览器的缓存,看看所要访问的域名是否存在于缓存之中,如果存在,则直接使用缓存中的IP地址进行访问,如果不存在,执行下一步
  • 缓存中没有找到,则调用系统的gethostbyname库函数,进行查询,gethostbyname函数会先检查域名是否在本地的Hosts文件中,如果找到直接返回域名对应的IP,(这也当访问不到某网址时,修改hosts文件的原因)如果没有找到则执行下一步
  • 向DNS服务器发送一个域名查询请求,然后就执行DNS查询过程,这个过程一般情况下会返回所要访问域名对应的IP地址,除非域名真的不存在,或者DNS服务器出现故障。

建立连接

  • 当浏览器得到了目标服务器的IP地址,以及 URL 中给出来端口号(http 协议默认端口号是 80, https 默认端口号是 443),它会调用系统库函数 socket ,请求一个 TCP流套接字。进行网络数据的传输。
  • 连接建立之后,则根据HTTP协议进行数据交换,资源通常是HTML 文件,也可能是 PDF,图片,或者其他类型的内容。

页面渲染

  • 浏览器获得资源文件后,HTML,css,js等文件则根据自身内核的机制,进行页面渲染,然后呈现给用户。

3.URL的合法性

官方API
参考链接:URLSearchParams
url-class
url-searchclass
手动检验:
2017-11-21 10 57 26

Example:
url-examples

4.URL编码

为什么要进行URL编码?通常如果一样东西需要编码,说明这样东西并不适合直接进行传输。

  • 1、会引起歧义:
    例如 URL 参数字符串中使用 key=value 这样的键值对形式来传参,键值对之间以 & 符号分隔,如 ?postid=5038412&t=1450591802326,服务器会根据参数串的 & 和 = 对参数进行解析,如果 value 字符串中包含了 = 或者 & ,如宝洁公司的简称为P&G,假设需要当做参数去传递,那么可能URL所带参数可能会是这样 ?name=P&G&t=1450591802326,因为参数中多了一个&势必会造成接收 URL 的服务器解析错误,因此必须将引起歧义的 & 和 = 符号进行转义, 也就是对其进行编码。
  • 2、非法字符:
    URL 的编码格式采用的是 ASCII 码,而不是 Unicode,这也就是说你不能在 URL 中包含任何非 ASCII 字符,例如中文。否则如果客户端浏览器和服务端浏览器支持的字符集不同的情况下,中文可能会造成问题。

encodeURI
encodeURI() 是 Javascript 中真正用来对 URL 编码的函数。它着眼于对整个URL进行编码。

encodeURI("http://www.cnblogs.com/season-huang/some other thing");
//"http://www.cnblogs.com/season-huang/some%20other%20thing";

编码后变为上述结果,可以看到空格被编码成了%20,而斜杠 / ,冒号 : 并没有被编码。
是的,它用于对整个 URL 直接编码,不会对 ASCII字母 、数字 、 ~ ! @ # $ & * ( ) = : / , ; ? + ‘ 进行编码。

encodeURI("~!@#$&*()=:/,;?+'")
// ~!@#$&*()=:/,;?+'

encodeURIComponent()
与encodeURI()的区别是,它用于对URL的组成部分进行个别编码,而不用于对整个URL进行编码。
因此,“; / ? : @ & = + $ , #”,这些在encodeURI()中不被编码的符号,在encodeURIComponent()中统统会被编码。至于具体的编码方法,两者是一样。

var param = "http://www.b.com?t=123&s=456"; // 要被编码的参数
URL = "http://www.a.com?foo="+encodeURIComponent(param);
//"http://www.a.com?foo=http%3A%2F%2Fwww.b.com%3Ft%3D123%26s%3D456"

5.URL相关设置获取

1>. 设置或获取整个 URL 为字符串
var url=window.location.href
返回结果:url https://www.baidu.com/
2>. 设置或获取 URL 的协议部分
var protocol= window.location.protocol;
返回结果: http:
3>. 设置或获取主机
var host =window.location.host
返回结果:www.baidu.com
4>. 设置或获取url端口
var port =window.location.port
返回结果: " " (如果采用默认的80端口(update:即使添加了:80),那么返回值并不是默认的80而是空字符)
5>. 设置或获取与 URL 的路径部分
url="http://echarts.baidu.com/option.html";
var pathname= window.location.pathname;
返回结果:"/option.html"
6>. 设置或获取 href 属性中跟在问号后面的部分
url="http://localhost:63342/project/6-21/aa.html?_ijt=flc0nna93fr89j3dlhh9mn7eco"
var param= window.location.search;
返回结果: "?_ijt=flc0nna93fr89j3dlhh9mn7eco"
7>. 设置或获取 href 属性中在井号“#”后面的分段
url="http://echarts.baidu.com/option.html#title.left"
var param= window.location. hash;
返回结果: "#title.left"

6.URL快捷方式

参考链接:HTTP权威指南--URL快捷方式

相对URL
URL扩展

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant