XHR对象用于与服务器交互。经过XMLHttpRequest
能够在不刷新页面的状况下请求特定URL,获取数据。XMLHttpRequest
在AJAX
编程中被大量使用。前端
MDN文档nginx
Fetch API提供了一个获取资源的接口(包括跨域请求)ajax
MDN文档编程
Asynchronous JavaScript And XML,是一种使用XMLHttpRequest
技术构建更复杂,动态的网页的编程实践。大部分的ajax其实就是对XMLHttpRequest
的相关API进行封装,使其使用起来更加方便。json
MDN文档segmentfault
跨域,顾名思义,跨越区域。大概意思为访问的网站请求非同源资源。后端
因为安全性等问题,浏览器自带同源策略,所谓同源是指域名,协议,端口均相同。当访问的网站须要请求非同源资源时,浏览器将拒绝这些非同源请求。在这种状况下,咱们须要解决浏览器跨域时拒绝请求非同源资源的限制。跨域
当浏览器出现跨域时,那就不可避免的引出两个关键的概念了。简单请求和非简单请求。 浏览器
当跨域产生时,非简单请求会在真正向服务端发送请求前进行预检请求(OPTIONS),。缓存
一、条件定义:若请求知足如下全部的条件,则请求可视为简单请求。
一、条件定义:若请求知足下列任一条件时,即应首先发送预检请求(options)。
JSON with Padding,是JSON的一种使用模式,可让网页从别的网域获取资料。因为同源策略,通常来讲位于server1.example.com的网页没法与不是server1.example.com的服务器沟通,而HTML的<script>元素是一个例外。利用<script>元素的这个开放策略,网页就能够实现跨域获取后端接口数据。
因为使用script标签的src属性,所以只支持get方法。
当使用JSONP这种方案时,先后端都要有相对应的写法。
大体流程就是,前端经过<script>标签的src属性向后台接口发起请求(只支持GET请求),而且传递参数callback='response'
,与此同时,前端必须定义函数response(responseData)
,这是用来处理接口返回数据后一些操做。
当接口收到请求,返回数据格式为response(responseData)
。这样,当前端接受到数据response(responseData)
,就恰好执行了咱们已经定义好的response(...)
当报错以下时:
缘由是:后端接口没有返回callback(...)
Cross Origin Resource Sharing,跨域资源共享,由一系列传输的HTTP头组成,这些HTTP头决定浏览器是否阻止前端JavaScript代码获取跨域请求的响应。
一、Access-Control-Allow-Origin:指示请求的资源能共享给哪些域
二、Access-Control-Allow-Credentials:指示当请求的凭证标记为true
时,是否响应该请求
三、Access-Control-Allow-Headers:用在对预请求的响应中,哪些HTTP方法容许访问请求的资源
四、Access-Control-Expose-Headers:指示哪些HTTP头的名称能在响应中列出
五、Access-Control-Max-Age:指示预请求的结果能被缓存多久
六、Access-Control-Request-Headers:用于发起一个预请求,告知服务器正式请求会使用哪些HTTP头
七、Access-Control-Request-Method:用于发起一个预请求,告知服务器正式请求会使用哪种HTTP请求方法
八、Origin:指示获取资源的请求是从什么域发起的
koa2中接口容许跨域响应,响应头部字段设置以下:
ctx.set('Access-Control-Allow-Origin', '*'); ctx.set('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, DELETE, PUT'); ctx.set('Access-Control-Allow-Headers', 'X-Requested-With, User-Agent, Referer, Content-Type, Cache-Control,accesstoken'); ctx.set('Access-Control-Max-Age', '86400'); ctx.set('Access-Control-Allow-Credentials', 'true');
注意事项:
若添加了自定义的Header字段,必须将这个字段名添加到服务端响应头部Access-Control-Allow-Headers中,否则会报错。
项目踩坑:
在接口响应中添加了以上容许跨域响应的头部字段,可是在开发中还报了跨域的错误(Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request
),报错的大体意思是预检请求禁止重定向。通过排查,发现是服务端nginx作了HTTP到HTTPS的重定向设置,而我刚好是以http+ip地址的形式发起请求的,那么请求就被重定向到https了,然而,浏览器发起的预检请求是禁止重定向的,所以报错了。解决方案就是将请求地址改成https+域名的形式,这样预检请求就不会重定向了。