耦合性:也称块间联系。指软件系统结构中各模块间相互联系紧密程度的一种度量。模块之间联系越紧密,其耦合性就越强,模块的独立性则越差。模块间耦合高低取决于模块间接口的复杂性、调用的方式及传递的信息css
内聚性:又称块内联系。指模块的功能强度的度量,即一个模块内部各个元素彼此结合的紧密程度的度量。若一个模块内各元素(语名之间、程序段之间)联系的越紧密,则它的内聚性就越高。html
应用层:是体系结构中的最高。直接为用户的应用进程提供服务。在因特网中的应用层协议不少,如支持万维网应用的HTTP协议,支持电子邮件的SMTP协议,支持文件传送的FTP协议等等。html5
运输层:运输层主要使用如下两种协议:
(1) 传输控制协议TCP(Transmission Control Protocol):面向链接的,数据传输的单位是报文段,可以提供可靠的交付。
(2) 用户数据包协议UDP(User Datagram Protocol):无链接的,数据传输的单位是用户数据报,不保证提供可靠的交付,只能提供“尽最大努力交付”。linux
网络层:负责为分组交换网上的不一样主机提供通讯服务。在发送数据时,网络层把运输层残生的报文段或用户数据报封装成分组或包进行传送。在TCP/IP体系中,因为网络层使用IP协议,所以分组也叫作IP数据报,或简称为数据报。css3
数据链路层:网桥(现已不多使用)、以太网交换机(二层交换机)、网卡(其实网卡 是一半工做在物理层、一半工做在数据链路层)nginx
物理层:在物理层上所传数据的单位是比特。物理层的任务就是透明地传送比特流。git
所谓的“三次握手”即对每次发送的数据量是怎样跟踪进行协商使数据段的发送和接收同步,根据所接收到的数据量而肯定的数据确认数及数据发送、接收完毕后什么时候撤消联系,并创建虚链接。github
第一次握手:创建链接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。web
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时本身也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;面试
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP链接成功)状态,完成三次握手。
协议是指计算机通讯网络中两台计算机之间进行通讯所必须共同遵照的规定或规则,超文本传输协议(HTTP)是一种通讯协议,它容许将超文本标记语言(HTML)文档从Web服务器传送到客户端的浏览器。
HTTP协议,即超文本传输协议(Hypertext transfer protocol)。是一种详细规定了浏览器和万维网(WWW = World Wide Web)服务器之间互相通讯的规则,经过因特网传送万维网文档的数据传送协议。
HTTP协议是用于从WWW服务器传输超文本到本地浏览器的传送协议。它可使浏览器更加高效,使网络传输减小。它不只保证计算机正确快速地传输超文本文档,还肯定传输文档中的哪一部分,以及哪部份内容首先显示(如文本先于图形)等。
HTTP是一个应用层协议,由请求和响应构成,是一个标准的客户端服务器模型。HTTP是一个无状态的协议。
在Internet中全部的传输都是经过TCP/IP进行的。HTTP协议做为TCP/IP模型中应用层的协议也不例外。HTTP协议一般承载于TCP协议之上,有时也承载于TLS或SSL协议层之上,这个时候,就成了咱们常说的HTTPS。以下图所示:(SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通讯提供安全及数据完整性的一种安全协议。TLS与SSL在传输层对网络链接进行加密。)
HTTP默认的端口号为80,HTTPS的端口号为443。
浏览网页是HTTP的主要应用,可是这并不表明HTTP就只能应用于网页的浏览。HTTP是一种协议,只要通讯的双方都遵照这个协议,HTTP就能有用武之地。好比我们经常使用的QQ,迅雷这些软件,都会使用HTTP协议(还包括其余的协议)。
2、简史
它的发展是万维网协会(World Wide Web Consortium)和Internet工做小组IETF(Internet Engineering Task Force)合做的结果,(他们)最终发布了一系列的RFC,RFC 1945定义了HTTP/1.0版本。其中最著名的就是RFC 2616。RFC 2616定义了今天广泛使用的一个版本——HTTP 1.1。
3、特色
HTTP协议永远都是客户端发起请求,服务器回送响应。这样就限制了使用HTTP协议,没法实如今客户端没有发起请求的时候,服务器将消息推送给客户端。
HTTP协议的主要特色可归纳以下:
1、支持客户/服务器模式。支持基本认证和安全认证。
2、简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法经常使用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不一样。因为HTTP协议简单,使得HTTP服务器的程序规模小,于是通讯速度很快。
3、灵活:HTTP容许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
4、HTTP 0.9和1.0使用非持续链接:限制每次链接只处理一个请求,服务器处理完客户的请求,并收到客户的应答后,即断开链接。HTTP 1.1使用持续链接:没必要为每一个web对象建立一个新的链接,一个链接能够传送多个对象,采用这种方式能够节省传输时间。
5、无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺乏状态意味着若是后续处理须要前面的信息,则它必须重传,这样可能致使每次链接传送的数据量增大。
无状态协议:
协议的状态是指下一次传输能够“记住”此次传输信息的能力。
http是不会为了下一次链接而维护此次链接所传输的信息,为了保证服务器内存。
好比客户得到一张网页以后关闭浏览器,而后再一次启动浏览器,再登录该网站,可是服务器并不知道客户关闭了一次浏览器。
因为Web服务器要面对不少浏览器的并发访问,为了提升Web服务器对并发访问的处理能力,在设计HTTP协议时规定Web服务器发送HTTP应答报文和文档时,不保存发出请求的Web浏览器进程的任何状态信息。这有可能出现一个浏览器在短短几秒以内两次访问同一对象时,服务器进程不会由于已经给它发过应答报文而不接受第二期服务请求。因为Web服务器不保存发送请求的Web浏览器进程的任何信息,所以HTTP协议属于无状态协议(Stateless Protocol)。
HTTP协议是无状态的和Connection: keep-alive的区别:
无状态是指协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。从另外一方面讲,打开一个服务器上的网页和你以前打开这个服务器上的网页之间没有任何联系。
HTTP是一个无状态的面向链接的协议,无状态不表明HTTP不能保持TCP链接,更不能表明HTTP使用的是UDP协议(无链接)。
从HTTP/1.1起,默认都开启了Keep-Alive,保持链接特性,简单地说,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP链接不会关闭,若是客户端再次访问这个服务器上的网页,会继续使用这一条已经创建的链接。
Keep-Alive不会永久保持链接,它有一个保持时间,能够在不一样的服务器软件(如Apache)中设定这个时间。
4、工做流程
一次HTTP操做称为一个事务,其工做过程可分为四步:
1)首先客户机与服务器须要创建链接。只要单击某个超级连接,HTTP的工做开始。
2)创建链接后,客户机发送一个请求给服务器,请求方式的格式为:统一资源标识符(URL)、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和可能的内容。
3)服务器接到请求后,给予相应的响应信息,其格式为一个状态行,包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容。
4)客户端接收服务器所返回的信息经过浏览器显示在用户的显示屏上,而后客户机与服务器断开链接。
若是在以上过程当中的某一步出现错误,那么产生错误的信息将返回到客户端,有显示屏输出。对于用户来讲,这些过程是由HTTP本身完成的,用户只要用鼠标点击,等待信息显示就能够了。
HTTP是基于传输层的TCP协议,而TCP是一个端到端的面向链接的协议。所谓的端到端能够理解为进程到进程之间的通讯。因此HTTP在开始传输以前,首先须要创建TCP链接,而TCP链接的过程须要所谓的“三次握手”。下图所示TCP链接的三次握手。
在TCP三次握手以后,创建了TCP链接,此时HTTP就能够进行传输了。一个重要的概念是面向链接,既HTTP在传输完成之间并不断开TCP链接。在HTTP1.1中(经过Connection头设置)这是默认行为。
100-199:表示信息性代码,标示客户端应该采起的其余动做,请求正在进行。
200-299:表示客户请求成功。
300-399:表示用于已经移走的资源文件,指示新的地址。 重定向
400-499:表示由客户端引起的错误。
500-599:表示由服务器端引起的错误。
404 没找到页面(not found)
403 禁止访问(forbidden)
200 一切正常(ok)
302/307 临时重定向
301 永久重定向
304 没有被修改(not modified)(服务器返回304状态,表示源文件没有被修改)从缓存中读取
按照响应信息的格式,先有状态行,再有消息体,因此注意在使用PrintWriter向客户端输出信息以前,设置状态码
设置HTTP响应头
目的用于告诉客户端
发送回来的内容的类型
有多少内容被正被发送
发送内容的服务器的类型
设置响应头的方法:setHeader()或setHeaders()。注意:设置响应头只能是HTTP协议。因此setHeader和setHeaders()都是HttpServletResponse中的方法
设置HTTP消息体
response.getWriter()得到打印字符流,能够输出文本
response.getOutputStream()得到输出字节流,能够发送二进制数据。
重定向调用方法:
response.sendRedirect(“http://127.0.0.1:8080/lovobook/bar.html“);
1,
浏览器向服务器发送HTTP请求。
2,服务器接收到请求后,若是调用response.sendRedirect()方法,表示资源已被移走。则发送一个302的状态码和location的响应头。在location响应头指明要转发的地址。 302:临时重定向
3,浏览器在接收到302状态码后,会读取location响应头的内容,并将地址栏的值赋为location响应头的内容。从而再向服务器发出第二次请求。因为是二次请求,因此重定向不能得到封装在request中的属性信息
转发是服务器行为,重定向是客户端行为
转发的速度快;重定向速度慢
一、 内部转发由requestDispatcher发出,重定向由response发出。
二、内部转发是一次请求,重定向是两次不一样请求。
三、内部转发能够取出request中封装的数据(携带参数),重定向不能。
四、 转发地址栏没有变化,重定向地址栏有变化
5、内部转发只能在服务器内部进行,重定向能够请求别的服务器。
五、 转发不会执行转发后的代码,重定向会执行重定向以后的代码
在servlet中调用转发、重定向的语句以下:
//转发到
request.getRequestDispatcher("new.jsp").forward(request, response);
//重定向
response.sendRedirect("new.jsp");
在controller层转发、重定向语句以下:
//转发
@RequestMapping("/index")
public String index(){
//some code
return "index/index"; //默认是转发,不会显示转发路径
}
@RequestMapping("/index")
public ModelAndView index(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("index/index"); //默认转发,跳到此页面
return modelAndView;
}
上述转发的路径是转发到存放jsp页面的路径,就是index文件夹下的index.jsp。
但若是加上forward,
就是转发到controller层的控制类下的方法(命名空间/RequestMapping)
return "forward:index/index";
modelAndView.setViewName("forward:index/index");
//重定向 (加上redirect)
@RequestMapping("/index")
public String index(){
//some code
return "redirect:index/index"; //地址栏显示重定向路径
}
@RequestMapping("/index")
public ModelAndView index(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("redirect:index/index");
return modelAndView;
}
转发过程:客户浏览器发送http请求,web服务器接受此请求,调用内部的一个方法在容器内部完成请求处理和转发动做,将目标资源发送给客户;在这里,转发的路径必须是同一个web容器下的url,其不能转向到其余的web路径上去,中间传递的是本身的容器内的request。在客户浏览器路径栏显示的仍然是其第一次访问的路径,也就是说客户是感受不到服务器作了转发的。转发行为是浏览器只作了一次访问请求。
重定向过程:客户浏览器发送http请求,web服务器接受后发送302状态码响应及对应新的location给客户浏览器,客户浏览器发现是302响应,则自动再发送一个新的http请求,请求url是新的location地址,服务器根据此请求寻找资源并发送给客户。在这里location能够重定向到任意URL,既然是浏览器从新发出了请求,则就没有什么request传递的概念了。在客户浏览器路径栏显示的是其重定向的路径,客户能够观察到地址的变化的。重定向行为是浏览器作了至少两次的访问请求的。
重定向,实际上是两次request
第一次,客户端request A,服务器响应,并response回来,告诉浏览器,你应该去B。这个时候IE能够看到地址变了,并且历史的回退按钮也亮了。重定向能够访问本身web应用之外的资源。在重定向的过程当中,传输的信息会被丢失。
在翻译好的类中,在_jspService()中有九个局部变量,并都作了初始化。因为咱们在JSP中书写的内容都是丰富_jspService()方法,因此能够直接使用这些局部变量,这就是隐式对象
四个做用域:
page:在一个页面内保存属性,跳转以后无效。page对象表明JSP自己,只有在JSP页面内才是合法的。
request:做用于请求 :在一次服务请求范围内,服务器跳转后依然有效,request对象表明了客户端的请求信息,主要用于接受经过HTTP协议传送到服务器的数据
session:做用于会话 :在一次会话范围内,不管何种跳转均可以使用,可是关闭浏览器后,新开浏览器没法使用。session对象是由服务器自动建立的与用户请求相关的对象。服务器为每一个用户都生成一个session对象,用于保存该用户的信息,跟踪用户的操做状态
application:做用于全局(类型是ServletContext) :整个服务器上保存,全部用户均可以使用。application对象可将信息保存在服务器中,直到服务器关闭,不然application对象中保存的信息会在整个应用中都有效
response:表明的是对客户端的响应,主要是将JSP容器处理过的对象传回到客户端
out:对象用于在Web浏览器内输出信息,而且管理应用服务器上的输出缓冲区pageContext 对象的做用是取得任何范围的参数
config:对象的主要做用是取得服务器的配置信息
exception:对象的做用是显示异常信息
事务在英文中是transaction,和现实世界中的交易很相似,它有以下四个特性:
事务的特性:
1、A (Atomicity) 原子性
原子性很容易理解,也就是说事务里的全部操做要么所有作完,要么都不作,事务成功的条件是事务里的全部操做都成功,只要有一个操做失败,整个事务就失败,须要回滚。
好比银行转帐,从A帐户转100元至B帐户,分为两个步骤:1)从A帐户取100元;2)存入100元至B帐户。这两步要么一块儿完成,要么一块儿不完成,若是只完成第一步,第二步失败,钱会莫名其妙少了100元。
2、C (Consistency) 一致性
一致性也比较容易理解,也就是说数据库要一直处于一致的状态,事务的运行不会改变数据库本来的一致性约束。
例如现有完整性约束a+b=10,若是一个事务改变了a,那么必须得改变b,使得事务结束后依然知足a+b=10,不然事务失败。
3、I (Isolation) 独立性
所谓的独立性是指并发的事务之间不会互相影响,若是一个事务要访问的数据正在被另一个事务修改,只要另一个事务未提交,它所访问的数据就不受未提交事务的影响。
好比如今有个交易是从A帐户转100元至B帐户,在这个交易还未完成的状况下,若是此时B查询本身的帐户,是看不到新增长的100元的。
4、D (Durability) 持久性
持久性是指一旦事务提交后,它所作的修改将会永久的保存在数据库上,即便出现宕机也不会丢失。
1.因为HTTP协议是无状态的协议,因此服务端须要记录用户的状态时,就须要用某种机制来识具体的用户,这个机制就是Session.典型的场景好比购物车,当你点击下单按钮时,因为HTTP协议无状态,因此并不知道是哪一个用户操做的,因此服务端要为特定的用户建立了特定的Session,用用于标识这个用户,而且跟踪用户,这样才知道购物车里面有几本书。这个Session是保存在服务端的,有一个惟一标识。在服务端保存Session的方法不少,内存、数据库、文件都有。集群的时候也要考虑Session的转移,在大型的网站,通常会有专门的Session服务器集群,用来保存用户会话,这个时候 Session 信息都是放在内存的,使用一些缓存服务好比Memcached之类的来放 Session。
2. 思考一下服务端如何识别特定的客户?这个时候Cookie就登场了。每次HTTP请求的时候,客户端都会发送相应的Cookie信息到服务端。实际上大多数的应用都是用 Cookie 来实现Session跟踪的,第一次建立Session的时候,服务端会在HTTP协议中告诉客户端,须要在 Cookie 里面记录一个Session ID,之后每次请求把这个会话ID发送到服务器,我就知道你是谁了。有人问,若是客户端的浏览器禁用了 Cookie 怎么办?通常这种状况下,会使用一种叫作URL重写的技术来进行会话跟踪,即每次HTTP交互,URL后面都会被附加上一个诸如 sid=xxxxx 这样的参数,服务端据此来识别用户。
3. Cookie其实还能够用在一些方便用户的场景下,设想你某次登录过一个网站,下次登陆的时候不想再次输入帐号了,怎么办?这个信息能够写到Cookie里面,访问网站的时候,网站页面的脚本能够读取这个信息,就自动帮你把用户名给填了,可以方便一下用户。这也是Cookie名称的由来,给用户的一点甜头。
Session是在服务端保存的一个数据结构,用来跟踪用户的状态,这个数据能够保存在集群、数据库、文件中;
Cookie是客户端保存用户信息的一种机制,用来记录用户的一些信息,也是实现Session的一种方式。存储量过小,只有 4KB
Expires是Web服务器响应消息头字段,在响应http请求时告诉浏览器在过时时间前浏览器能够直接从浏览器缓存取数据,而无需再次请求。
注:Date头域表示消息发送的时间,时间的描述格式由rfc822定义。例如,Date: Mon,31 Dec 2001 04:25:57GMT。
Web服务器告诉浏览器在2012-11-28 03:30:01这个时间点以前,可使用缓存文件。发送请求的时间是2012-11-28 03:25:01,即缓存5分钟。
不过Expires 是HTTP 1.0的东西,如今默认浏览器均默认使用HTTP 1.1,因此它的做用基本忽略。
Cache-Control与Expires的做用一致,都是指明当前资源的有效期,控制浏览器是否直接从浏览器缓存取数据仍是从新发请求到服务器取数据。只不过Cache-Control的选择更多,设置更细致,若是同时设置的话,其优先级高于Expires。
http协议头Cache-Control : |
值能够是public、private、no-cache、no- store、no-transform、must-revalidate、proxy-revalidate、max-age 各个消息中的指令含义以下:
|
仍是上面那个请求,web服务器返回的Cache-Control头的值为max-age=300,即5分钟(和上面的Expires时间一致,这个不是必须的)。
Last-Modified/If-Modified-Since要配合Cache-Control使用。
l Last-Modified:标示这个响应资源的最后修改时间。由服务器往客户端发送的http头,web服务器在响应请求时,告诉浏览器资源的最后修改时间。
l If-Modified-Since:响应资源最后修改的时间,由客户端往服务端发送的头。再次请求本地存在的 cache 页面时,客户端会经过 If-Modified-Since 头将先前服务器端发过来的 Last-Modified 最后修改时间戳发送回去,这是为了让服务器端进行验证,经过这个时间戳判断客户端的页面是不是最新的,若是不是最新的,则返回200,返回新的内容。若是是最新的,则 返回 304 告诉客户端其本地 cache 的页面是最新的,因而客户端就能够直接从本地加载页面了,这样在网络上传输的数据就会大大减小,同时也减轻了服务器的负担。
Etag/If-None-Match也要配合Cache-Control使用。
l Etag:服务端往客服端发送的头。web服务器响应请求时,告诉浏览器当前资源在服务器的惟一标识(生成规则由服务器决定)。Apache中,ETag的值,默认是对文件的索引节(INode),大小(Size)和最后修改时间(MTime)进行Hash后获得的。
l If-None-Match:(Etags的值),客户端往服务端发送的头。工做原理是在HTTP Response中添加ETags信息。当客户端再次请求该资源时,将在HTTP Request中加入If-None-Match信息(ETags的值)。若是服务器验证资源的ETags没有改变(该资源没有改变),将返回一个304状态;不然,服务器将返回200状态,并返回该资源和新的ETags。
你可能会以为使用Last-Modified已经足以让浏览器知道本地的缓存副本是否足够新,为何还须要Etag(实体标识)呢?HTTP1.1中Etag的出现主要是为了解决几个Last-Modified比较难解决的问题:
l Last-Modified标注的最后修改只能精确到秒级,若是某些文件在1秒钟之内,被修改屡次的话,它将不能准确标注文件的修改时间
l 若是某些文件会被按期生成,当有时内容并无任何变化,但Last-Modified却改变了,致使文件无法使用缓存
l 有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形
Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的惟一标识符,可以更加准确的控制缓存。Last-Modified与ETag是能够一块儿使用的,服务器会优先验证ETag,一致的状况下,才会继续比对Last-Modified,最后才决定是否返回304。
浏览器缓存行为还有用户的行为有关!!!
用户操做 |
Expires/Cache-Control |
Last-Modified/Etag |
地址栏回车 |
有效 |
有效 |
页面连接跳转 |
有效 |
有效 |
新开窗口 |
有效 |
有效 |
前进、后退 |
有效 |
有效 |
F5刷新 |
无效 |
有效 |
Ctrl+F5刷新 |
无效 |
无效 |
统一资源标志符URI:就是在某一规则下能把一个资源独一无二地标识出来。
拿人作例子,身份证号就是URI,经过身份证号能让咱们能且仅能肯定一我的。
统一资源定位符URL:也拿人作例子:动物住址协议://地球/中国/浙江省/杭州市/西湖区/某大学/14号宿舍楼/525号寝/张三.人
能够看到,这个字符串一样标识出了惟一的一我的,起到了URI的做用,因此URL是URI的子集。URL是以描述资源的位置来惟一肯定一个资源的。
因此不管是用定位的方式仍是用编号的方式,咱们均可以惟一肯定一我的,都是URl的一种实现,而URL就是用定位的方式实现的URI。
回到Web上,假设全部的Html文档都有惟一的编号,记做html:xxxxx,xxxxx是一串数字,即Html文档的身份证号码,这个能惟一标识一个Html文档,那么这个号码就是一个URI。
而URL则经过描述是哪一个主机上哪一个路径上的文件来惟一肯定一个资源,也就是定位的方式来实现的URI。
事件传播的顺序对应浏览器的两种事件流模型:捕获型事件流和冒泡型事件流。
DOM标准采用捕获+冒泡。两种事件流都会触发DOM的全部对象,从document对象开始,也在document对象结束。
DOM标准规定事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。
事件捕获阶段:实际目标(<div>)在捕获阶段不会接收事件。也就是在捕获阶段,事件从document到<html>再到<body>就中止了。上图中为1~3.
处于目标阶段:事件在<div>上发生并处理。可是事件处理会被当作是冒泡阶段的一部分。上图中为4
冒泡阶段:事件又传播回文档。上图中为5~7
阻止事件冒泡:
如有一a标签:
<a href="http://www.baidu.com" target="_blank"></a>
1.event.stopPropagation()方法
这是阻止事件的冒泡方法,不让事件向documen上蔓延,可是默认事件任然会执行,当你掉用这个方法的时候,若是点击一个链接,这个链接仍然会被打开,不会冒泡到父元素直至document
2.event.preventDefault()方法
这是阻止默认事件的方法,调用此方法是,链接不会被打开,可是会发生冒泡,冒泡会传递到上一层的父元素;
3.return false ;
这个方法比较暴力,他会同时阻止事件冒泡也会阻止默认事件;写上此代码,链接不会被打开,事件也不会传递到上一层的父元素;能够理解为return false就等于同时调用了event.stopPropagation()和event.preventDefault(),但能够在return false以前执行一些必要代码。但标签内部的事件不会执行
了解同源政策:所谓"同源"指的是"三个相同"。
设想这样一种状况:A网站是一家银行,用户登陆之后,又去浏览其余网站。若是其余网站能够读取A网站的 Cookie,会发生什么?
很显然,若是 Cookie 包含隐私(好比存款总额),这些信息就会泄漏。更可怕的是,Cookie 每每用来保存用户的登陆状态,若是用户没有退出登陆,其余网站就能够冒充用户,随心所欲。由于浏览器同时还规定,提交表单不受同源政策的限制。
因而可知,"同源政策"是必需的,不然 Cookie 能够共享,互联网就毫无安全可言了。
首先假设你请求数据的网站为B。要看你是否能够控制(修改里面的代码)。
1 jsonp 缺点:只能get请求 ,须要修改B网站的代码
2 cors 这个方案缺点 是 ie6 7 兼容很差(却是不见得要兼容)。须要B网站在响应中加头
3 postMessage 缺点也是 ie6 7 兼容很差(却是不见得要兼容)。须要修改B网站的代码
4 iframe window.name 传值得方式很巧妙,兼容性也很好。可是也是须要你能修改B网站代码
5 服务端主动请求B网站,兼容性好并且你客户端的代码仍是原来的ajax,缺点是感受很差。(服务器端是不存在跨域安全限制的)
6 相似5 用nginx把B网站的数据url反向代理。
若是你不能修改B网站的代码老老实实5 6 方案
若是能修改B网站 方案2的修改应该是最简单的。
就算是B网站你能够修改,还有种需求处理起来比较麻烦的,就是有的数据须要登陆以后才能取。
最直接的方案,B网站提供数据的url 进去先提供用户名密码,走下登陆再走取数据,最后返回数据。
Jsonp解决跨域:
1 $.ajax({ 2 3 url:url, 4 5 dataType:'jsonp', 6 7 processData: false, 8 9 type:'get', 10 11 success:function(data){ 12 13 alert(data.name); 14 15 }, 16 17 error:function(XMLHttpRequest, textStatus, errorThrown) { 18 19 alert(XMLHttpRequest.status); 20 21 alert(XMLHttpRequest.readyState); 22 23 alert(textStatus); 24 25 } 26 27 });
jsonp其实返回的是一个JS函数调用代码,把返回的数据和客户端能调用的函数名拼接在一块儿,放到浏览器环境下,去执行而获得最终的服务端数据,也就是jsonp是一种json数据的传输方式而不是格式
callback({
"message":"获取成功",
"state":"1",
"result":{"name":"工做组1","id":1,"description":"11"}
})
闭包是指有权访问另外一个函数做用域中的局部变量的函数. 建立闭包常见方式,就是在一个函数内部建立另外一个函数.
应用场景 设置私有变量和方法
不适合场景:返回闭包的函数是个很是大的函数
闭包的缺点就是常驻内存,会增大内存使用量,使用不当很容易形成内存泄露。
受JavaScript链式做用域结构的影响,父级变量中没法访问到子级的变量值,为了解决这个问题,才使用闭包这个概念
像html5的新的标签header,footer,section等就是语义化
一方面,语义化就是让计算机可以快速的读懂内容,高效的处理信息,能够对搜索引擎更友好。
另外一方面,便于与他人的协做,他人经过读代码就能够理解你网页标签的意义。
content-box 是W3C的标准盒模型 元素宽度=内容宽度+padding+border
border-box 是ie的怪异盒模型 他的元素宽度等于内容宽度, 内容宽度包括了 padding+border,只要设定了宽度高度,再设置padding 和 border 也不会撑大
好比有时候在元素基础上添加内距padding或border会将布局撑破 可是使用border-box就能够轻松完成
Inherit:规定应从父元素继承 box-sizing 属性的值。
圆角边框border-radius,添加阴影框 box-shadow / text-shadow
颜色渐变
2d 3d 转换:transform
过分 transition
动画 @keyframes
媒体查询 @media 响应式优化
HTML5增长了新的内容标签,这些标签带有必定的语义,使搜索引擎爬取你的网站信息更高效。
HTML4中的内容标签级别相同,没法区分各部份内容。而HTML5中的内容标签互相独立,级别不一样,搜索引擎以及统计软件等都可快速识别各部份内容。
最先的Cookies天然是你们都知道,问题主要就是过小,大概也就4KB的样子,并且IE6只支持每一个域名20个cookies,太少了。
在HTML5中,本地存储是一个window的属性,包括localStorage和sessionStorage,从名字应该能够很清楚的辨认两者的区别,前者是一直存在本地的,后者只是伴随着session,窗口一旦关闭就没了。两者用法彻底相同
label标签来定义表单控制间的关系,当用户选择该标签时,浏览器会自动将焦点转到和标签相关的表单控件上。
<label for="Name">Number:</label>
<input type=“text“name="Name" id="Name"/>
<label>Date:<input type="text" name="B"/></label>
是一种常见的特性,即抓取对象之后拖到另外一个位置。在 HTML5 中,拖放是标准的一部分,任何元素都可以拖放。
设置元素为可拖放
首先,为了使元素可拖动,把 draggable 属性设置为 true :
当离开的时候 ondragleave
当进入的时候ondragenter
拖动什么 - ondragstart 和 setData()
放到何处 - ondragover :内部移动
进行放置 - ondrop
1 //建立一个FormData对象:用一些键值对来模拟一系列表单控件:即把form中全部表单元素的name与value组装成一个queryString 2 3 var form = new FormData(); 4 5 //设置要传递的参数 6 7 form.append("doc", fileObj); 8 9 // 建立一个ajax对象 10 11 var xhr = new XMLHttpRequest(); 12 13 //规定请求的类型、URL 以及是否异步处理请求。true为异步 14 15 //请求是异步的。由于要实时获取到上传的进度,则请求需是异步的,若是是同步的话,会直到请求完成才能获取到响应 16 17 xhr.open("post", url, true); 18 19 //发送http请求:将请求发送到服务器,与后台交互 20 21 xhr.send(form); //也能够不携带参数,直接 xhr.send(); 22 23 //响应成功进入的回调函数 24 25 xhr.onreadystatechange = function(){ 26 27 //状态4和200表明和服务器端交互成功 28 29 if(xhr.readyState==4 && xhr.status==200){ 30 31 //获取上传成功的返回数据 32 33 var data = xhr.responseText.trim(); 34 35 jdata = eval("("+data+")"); 36 37 } 38 39 };
//xhr.open() 与 xhr.send() 一块儿用
//前者是规定请求的类型、url,后者是发送请求到这个url
问题一:不一样浏览器的标签默认的外补丁和内补丁不一样
:last-child 选择元素最后一个孩子
:first-child 选择元素第一个孩子
:nth-child(1) 按照第几个孩子给它设置样式
:nth-child(even) 按照偶数
:nth-child(odd) 按照奇数
a:link {color: #FF0000} /* 未访问的连接 */
a:visited {color: #00FF00} /* 已访问的连接 */
a:hover {color: #FF00FF} /* 鼠标移动到连接上 */
a:active {color: #0000FF} /* 选定的连接 */
:after 选择器在被选元素的内容后面插入内容。使用 content 属性来指定要插入的内容。
详情看:https://github.com/Krryxa/WORK-LEARNING/issues/9
链接两个或更多的数组,并返回结果。 |
|
把数组的全部元素放入一个字符串。元素经过指定的分隔符进行分隔。 |
|
删除并返回数组的最后一个元素(改变原数组) |
|
向数组的末尾添加一个或更多元素,并返回新的长度。(改变原数组) |
|
颠倒数组中元素的顺序。(改变原数组) |
|
删除并返回数组的第一个元素(改变原数组) |
|
从某个已有的数组返回选定的元素 |
|
对数组的元素进行排序(改变原数组) |
|
删除元素,并向数组添加新元素。(改变原数组) |
|
返回该对象的源代码。 |
|
把数组转换为字符串,并返回结果。 |
|
把数组转换为本地数组,并返回结果。 |
|
向数组的开头添加一个或更多元素,并返回新的长度。(改变原数组) |
|
返回数组对象的原始值 |
第一种: new关键字改变this指向
1 // 构造函数版 this 2 function Fn(){ 3 this.user = "筱月"; // 此时的 this 指向 window 4 } 5 let a = new Fn(); 6 console.log(a.user); //筱月
用变量a建立了一个 Fn 的实例,此时仅仅只是建立,并无执行,而调用这个函数 Fn 的是对象 a,那么 this 指向的天然是对象 a,那么为何对象 a 中会有 user,由于你已经复制了一份 Fn 函数到对象 a 中,用了 new 关键字就等同于复制了一份
第二种: call()
注意若是 call 和 apply 的第一个参数写的是null,那么 this 指向的是 window 对象
1 let a = { 2 user:"筱月", 3 fn:function(){ 4 console.log(this.user); //筱月 5 } 6 } 7 let b = a.fn; 8 // 执行 b 方法,call 的第一个参数是改变 this 指向,b 方法的 this 就是指向 call 第一个参数的对象 9 b.call(a); // 若不用call,则 b() 执行后 this 指的是 Window 对象
// call方法除了第一个参数之外还能够添加多个参数,以下: let a = { user:"筱月", fn:function(e,ee){ console.log(this.user); // 筱月 console.log(e+ee); // 3 } } let b = a.fn; b.call(a,1,2); // 输出 筱月 3
第三种:apply()
1 let a = { 2 user:"筱月", 3 fn:function(){ 4 console.log(this.user); //筱月 5 } 6 } 7 8 let b = a.fn; 9 b.apply(a); 10 11 // apply方法和call方法有些类似,它也能够改变this的指向,也能够有多个参数,可是不一样的是,第二个参数必须是一个数组,以下: 12 13 let a = { 14 user:"筱月", 15 fn:function(e,ee){ 16 console.log(this.user); //筱月 17 console.log(e+ee); //11 18 } 19 } 20 21 let b = a.fn; 22 b.apply(a,[10,1]); 23 24 // 注意若是 call 和 apply 的第一个参数写的是null,那么this指向的是window对象 25 26 let a = { 27 user:"筱月", 28 fn:function(){ 29 console.log(this); // Window {...} 30 } 31 } 32 33 let b = a.fn; 34 b.apply(null);
第四种:bind()
bind方法和call、apply方法有些不一样,以下:
bind 方法返回的是一个修改事后的函数,此时并无调用,须要将 bind 方法返回的函数执行 才能调用
1 let a = { 2 user:"筱月", 3 fn:function(){ 4 console.log(this.user); //筱月 5 } 6 7 } 8 let b = a.fn; 9 let c = b.bind(a); // 方法还没执行,bind 方法返回的是一个修改事后的函数 10 c(); // 输出:筱月 11 12 // 一样bind也能够有多个参数,而且参数能够在 bind 返回的函数执行的时候再次添加,可是要注意的是,参数是按照形参的顺序进行的 13 let aa = { 14 user:"筱月", 15 fn:function(e,d,f){ 16 console.log(this.user); //筱月 17 console.log(e,d,f); //10 1 2 18 } 19 } 20 21 let bb = aa.fn; 22 let cc = bb.bind(aa,10); // 能够添加参数 23 cc(1,2); // 执行的时候能够继续添加参数
这里就将外部的 this 放进 callback 里面,callback 里面就可使用外部的 this
1 //代码一: 2 3 a(1); //执行这个会报错 4 5 var a = function(index){ 6 7 alert(index); 8 9 } 10 11 a(2); //执行这个不会报错
1 //代码二: 2 3 a(1); //执行这个不会报错 4 5 function a(index){ 6 7 alert(index); 8 9 } 10 11 a(2); //执行这个不会报错