标签:
想象用浏览器打开imooc.com网站,HTTP走过的环节:
1.首先,是对imooc.com域名解析,
(1.1)浏览器搜索浏览器自身的DNS缓存。(DNS(Domain Name System,域名系统),因特网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串)
(1.2)如果浏览器没有找到自身的DNS缓存或之前的缓存已失效,那么浏览器会搜索操作系统自身的DNS缓存。
(1.3)如果操作系统的DNS缓存也没有找到,那么系统会尝试在本地的HOST文件去找。(Hosts是一个没有扩展名的系统文件,可以用记事本等工具打开,其作用就是将一些常用的网址域名与其对应的IP地址建立一个关联“数据库”,当用户在浏览器中输入一个需要登录的网址时,系统会首先自动从Hosts文件中寻找对应的IP地址,一旦找到,系统会立即打开对应网页,如果没有找到,则系统再会将网址提交DNS域名解析服务器进行IP地址的解析)
(1.4)如果在HOST里依然没有找到,浏览器会发起一个DNS的系统调用,即一般向本地的宽带运营商发起域名解析请求。这后面又可以试情况分很多步骤,第一,宽带运营商服务器会首先查看自身的缓存,看是否有结果,如果没有,那么运营商服务器会发起一个迭代DNS解析请求(根域,顶级域,域名注册商),最终会返回对DNS解析的结果。运营商服务器然后把结果返回给操作系统内核(同时也缓存在自己的缓存区),然后操作系统把结果返回给浏览器。
(1.5)以上的最终结果,是让浏览器拿到imooc.com的IP地址,DNS解析完成。
2.然后,在浏览器获得域名的IP地址后,发起“三次握手”,建立TCP/IP连接。
3.在TCP/IP连接建立起来后,浏览器就可以向服务器发送HTTP请求了。比如,用HTTP的GET方法请求一个根域里的某个域名,协议可以采用HTTP 1.0 。
4.服务器端接受这个请求,根据路径参数,经过后端的一些处理之后,把处理后的一个结果以数据的形式返回给浏览器,如果是imooc.com网站的页面,服务器就会把完整的HTML页面代码返回给浏览器。
5.浏览器拿到了imooc.com这个网站的完整HTML页面代码,在解析和渲染这个页面的时候,里面的Javascript、CSS、图片等静态资源,它们同样也是一个个HTTP请求,都需要经过上面的步骤来获取。
6.浏览器根据拿到的资源对页面进行渲染,最终把一个完整的页面呈现出来。
可以简单地把http拆分成请求和响应,然后他们都有http头和正文信息,http头发送的是一些附加的信息:内容类型,服务器发送响应的日期,http状态码。正文就是用户提交的表单数据。
域名解析->域名 ->缓存->根域dns->顶级域dns->本域dns->服务器IP
1.搜索浏览器自身DNS缓存,如果不存在或者过期(>60s)放弃
2.搜索操作系统自身的dns缓存
3.读取本地的HOST文件
4.浏览器发起一个DNS的系统调用 域名解析
5.客户端通过随机端口使用tcp协议服务器ip的80端口发起连接请求 三次握手
6.tcp/ip连接请求建立后浏览器可以向服务器发起http请求
7.http客户端发起请求,创建端口,解析用户操作,拼接请求头信息
8.http客户端并向服务器的该端口发送request头信息
9.服务器监听端口 如80
10.http监听到发到80端口的请求头信息
11.http服务器解析头信息
12.http服务器 按照请求头信息,返回相应响应头信息response
13.响应头信息发送给http客户端,客户端解析响应头信息,并完成其他操作
14.完成一次http请求
waiting(TTFB):表示请求发出到收到响应中第一个字节所耗费的时间。
请求方法
get:请求资源
post:提交资源
put:更新
delete:删除
head:类似get
trace
options
服务器请求状态码:
1XX:指示信息,表示信息已接收,正在处理
2XX:已成功接收并处理。
3XX:重定向
4XX:客户端错误
5XX:服务器端错误
1XX请求已接收,正在处理XX
2XX,,请求接受成功,处理完成,成功返回,200=0k
3XX,,重定向
4XX,,客户端错误,400 有语法错误不能理解,401请求未授权,403拒绝提供服务,404 未找到改地址,对象不存在
5XX,,服务器端错误,500服务器发生未知错误,503服务器端当前不能处理
通过自己的理解这些问题
1.回调,即后续处理的函数作为参数出现在前驱函数中,对前驱函数中的一些操作进行处理
2.同步与异步
同步是指后一项任务必须在前一项任务执行完毕后执行,程序的执行顺序和任务的排列顺序是一致的
//同步 打电话 等待 查询 返回结果 挂电话 <br>
//异步 打电话 留号码 说明查询 挂电话 出结果 回电话 完成<br>
//同步 下载 等待 完成 看片儿<br>
//异步 下载a 下载b 下载c 下载完播放提示音看片儿 顺序不定<br>
3.单线程/多线程
今天周日,人多,但是你还是一个人给自己挂号,你就是单线程的
本周日,漩涡鸣人用多重影分身给自己挂号,鸣人就是多线程的
4.i/o
磁盘的写入 挂号的时候护士把你的信息录入,这就是写入
磁盘的读出 你挂完号去看病,轮到你了,医生把你的信息调出来,82岁 未婚, 哦,大龄单身狗啊,这就是读出
5.阻塞/非阻塞
医生告诉你你得好好检查检查,然后对你一阵敲敲打打,你啥也干不了,只能被动享受,你就被阻塞了
医生拍个片子就让你滚回家,说看看,过两天电话通知你结果,你想干啥就干啥,你就是非阻塞的
6.事件/事件驱动<br>
事件并不是立即执行,而是等待驱动(比如click)时才会被执行
为了某个事件注册了回调函数,但是这个回调函数不是马上执行,只有当事件发生的时候,才会调用回调函数,这种函数执行的方式叫做事件驱动~这种注册回调就是基于事件驱动的回调,如果这些回调和异步的I/O操作有关,可以看作是基于回调的异步I/O,只不过这种回调在nodejs中是有事件来驱动的
7.事件循环 回调函数队列
倘若有大量的异步操作以及io的耗时操作,甚至是定时器控制的延时操作,都要去调用相应的回调函数,从而完成密集任务,而又不会阻塞整个程序的流程,就需要一个机制来管理,这个机制就是event loop
作用域
访问变量或函数的能力,局部作用域可以访问其外部或全局作用域下的变量或函数,外部或全局作用域访问不了局部作用域。JS是函数级作用域;
上下文this
1.this在函数的内部使用
2.this指向的是函数拥有者
3.作为对象方法,this指向调用的对象自身;作为函数调用,this指向全局
call apply 改变this指定的对象的引用
b.setMessage.call(a,"a的消息"):a执行时,上下文对象调用b对象的setMessage方法,相当于a.setMessage("a的消息")。
另外,call和apply的区别在于:call将参数依次传递给借用的方法作参数;而apply直接将这些参数放到一个数组中再传递。
全局变量使用this,指向函数拥有者
构造函数使用this,指向新构建好的函数,实例对象。
call 和 apply 都是为了改变某个函数运行时的 context 即上下文而存在的,换句话说,就是为了改变函数体内部 this 的指向。
二者的作用完全一样,只是接受参数的方式不太一样。
例如,有一个函数 func1 定义如下:
var func1 = function(arg1, arg2) {};
就可以通过 func1.call(this, arg1, arg2); 或者 func1.apply(this, [arg1, arg2]); 来调用。其中 this 是你想指定的上下文,他可以任何一个 JavaScript 对象(JavaScript 中一切皆对象),call 需要把参数按顺序传递进去,而 apply 则是把参数放在数组里。
JavaScript 中,某个函数的参数数量是不固定的,因此要说适用条件的话,当你的参数是明确知道数量时,用 call,而不确定的时候,用 apply,然后把参数 push 进数组传递进去。当参数数量不确定时,函数内部也可以通过 arguments 这个数组来便利所有的参数。
标签:
原文地址:http://www.cnblogs.com/greatluoluo/p/5725082.html