Ajax与跨域的知识点

1,041 阅读17分钟

Ajax能够向服务器请求额外的数据而无需卸载页面

Ajax核心

Ajax核心就是XHR对象,浏览器通过XHR对象向服务器请求数据

XHR的用法

当请求被响应后,响应的数据会自动填充XHR对象的属性

  • responseText:作为响应主体被返回的文本
  • responseXML:如果响应内容类型是text/xml或application/xml,这个属性将保存响应数据的XML DOM文档
  • status:响应的HTTP状态
  • statusText:HTTP状态的说明

XHR对象的readyState属性表示请求/响应的当前活动阶段,这个属性可取如下值

  • 0:未初始化。尚未调用open方法
  • 1:启动。已经调用open方法但还没有调用send方法
  • 2:发送。已经调用send方法但还没有接收到响应
  • 3:接收。已经接收到部分响应数据
  • 4:完成。已经接收到全部响应数据,并且可以在客户端使用了。

我们发送的请求或者我们接收到的响应都会带有相应的头部信息,当我们发送请求时,我们能够在启动阶段修改这些信息。

  • setRequestHeader方法设置自定义的头部信息,这个方法接收两个参数,一是头部字段的名称,二是头部字段的值。

当我们接收到服务器响应之后,我们也可以获取响应的头部信息。

  • getResponseHeader方法获取相应的头部信息
  • getAllResponseHeaders方法获取一个包含所有头部信息的长字符串

发送请求的同时会发送哪些头部信息?

  1. Accept:浏览器能够处理的内容类型
  2. Accept-Charset:浏览器能够显示的字符集
  3. Accept-Encoding:浏览器能够处理的压缩编码
  4. Accept-Language:浏览器当前设置的语言
  5. Connection:浏览器与服务器之间的连接类型
  6. Cookie:当前页面设置的任何Cookie
  7. Host:发出请求的页面所在域
  8. Referer:发出请求页面的URL
  9. User-Agent:浏览器的用户代理字符串

GET请求与POST请求的区别

  1. Get请求向服务器索取数据,Post请求向服务器提交数据。

  2. GET请求把参数包含在URL中,将请求信息放在后面,以?分割URL和传输数据,参数之间以&相连,POST请求把提交的数据放在请求体中。

  3. get传送的数据量较小,不能大于2KB。post传送的数据量较大,一般被默认为不受限制。但理论上,IIS4中最大量为80KB,IIS5中为100KB。(实际上http协议并没有规定url的长度,对get做出限制的是各个浏览器,他们限制了输入的url的长度,不同浏览器限制的大小也是不一样的)

  4. get安全性非常低,get设计成传输数据,一般都在地址栏里面可以看到,post安全性较高,post传递数据比较隐私,所以在地址栏看不到, 如果没有加密,他们安全级别都是一样的,随便一个监听器都可以把所有的数据监听到。

  5. GET请求能够被缓存,GET请求会保存在浏览器的浏览记录中,以GET请求的URL能够保存为浏览器书签,post请求不具有这些功能。

  6. HTTP的底层是TCP/IP,GET和POST的底层也是TCP/IP,也就是说,GET/POST都是TCP链接。GET和POST能做的事情是一样一样的。你要给GET加上request body,给POST带上url参数,技术上是完全行的通的。

  7. GET产生一个TCP数据包,对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);POST产生两个TCP数据包,对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据),并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。

浏览器实现的方法fetch

fetch api是基于promise的设计,它是为了取代传统xhr的不合理的写法而生的。

使用fetch方法会返回一个promise对象,这让我们能够使用promise的链式操作风格。fetch接收两个参数,第一个是请求路径,第二个可选,是一个对象,用于控制许多不同的设置。fetch()如果得到了响应数据那么就会将响应对象返回,只需要在后面.then()就可以接收响应对象

 fetch('./a.html').then(date=>console.log(date))

如果请求的是json对象,对返回的响应对象调用json方法,返回被解析为json格式的promise对象

       fetch('./json.json').then((date)=> date.json()).then(date=>console.log(date))

第二个参数对象能够设置的信息有:

  • method:请求使用的方法,如GET、POST。
  • headers:请求的头信息,形式为Headers的对象或包含ByteString值的对象字面量。
  • body:请求的body信息:可能是一个Blob、BufferSource、FormData、URLSearchParams或者USVString对象。注意GET或HEAD方法的请求不能包含body信息。
  • mode:请求的模式,如cors、no-cors或者same-origin。
  • credentials:请求的credentials,如omit、same-origin或者include。为了在当前域名内自动发送cookie, 必须提供这个选项, 从Chrome 50开始, 这个属性也可以接受FederatedCredential实例或是一个PasswordCredential实例。
  • cache:请求的cache模式:default、no-store、reload、no-cache、force-cache或者only-if-cached。
  • redirect:可用的redirect模式: follow (自动重定向), error (如果产生重定向将自动终止并且抛出一个错误),或者manual (手动处理重定向).在Chrome中,Chrome 47之前的默认值是follow,从Chrome 47开始是manual。
  • referrer:一个USVString,可以是no-referrer、client或一个URL。默认是client。

常用的设置信息就是前四个,前三个就不多说了,说一下mode

  • same-origin表示必须同源,绝对禁止跨域,这个是老版本浏览器默认的安全策略。

  • cors表示允许跨域,顾名思义它是以CORS的形式跨域;当然该模式也可以同域请求。只需要服务器的响应头中带有Access-Control-Allow-Origin: *就行。

  • `no-cors`这个就很特殊了,字面意思是禁止以CORS的形式跨域,其实它的效果是,对外域的请求可以发送,外域服务器无论设不设`Access-Control-Allow-Origin: *`都会接收请求并处理请求,但是浏览器不接收响应,即使外域返回了内容,浏览器也当做没接到。

Response响应对象的方法

  • clone,创建一个Response对象的克隆
  • error,返回一个绑定了网络错误的新的Response对象
  • redirect,用另一个URL创建一个新的 response.
  • arrayBuffer,读取 Response对象并且将它设置为已读(因为Responses对象被设置为了 stream 的方式,所以它们只能被读取一次) ,并返回一个被解析为ArrayBuffer格式的promise对象
  • blob,读取 Response对象并且将它设置为已读(因为Responses对象被设置为了 stream 的方式,所以它们只能被读取一次) ,并返回一个被解析为Blob格式的promise对象
  • formDate,读取Response对象并且将它设置为已读(因为Responses对象被设置为了 stream 的方式,所以它们只能被读取一次) ,并返回一个被解析为FormData格式的promise对象
  • json,读取 Response对象并且将它设置为已读(因为Responses对象被设置为了 stream 的方式,所以它们只能被读取一次) ,并返回一个被解析为JSON格式的promise对象
  • text,读取 Response对象并且将它设置为已读(因为Responses对象被设置为了 stream 的方式,所以它们只能被读取一次) ,并返回一个被解析为USVString格式的promise对象

一个轻量的库axios

//这个库一直想看但一直在路上,等我看完回来补吧

跨域

同源策略,浏览器的安全策略,非同源数据不能直接相互访问。必须协议,域名,端口号一致才叫同源。跨域就是非同源情况下访问数据的处理办法

cors,跨域资源共享

  • 后端设置响应头,header('Access-Control-Allow-Origin:*'),表示允许所有地址访问
  • 后面的*表示所有,也可以填具体的地址,只有这个地址可以访问

jsonp

利用src属性开放性原则,来实现跨域

script标签中的src属性请求数据不受同源策略的影响,能够实现跨域

前端向后端请求数据,后端将数据作为参数传给函数,这个函数就是jsonp接口

<script>
    function fn(date){}
</script>
<script src='url'></script>//这里接收到的就是fn(数据),以这样的形式获得数据

我们也能把fn作为参数传递给服务器,这样就能保证服务器接口和函数名保持一致