关于跨域:谈谈跨域那些事

10次阅读

共计 2847 个字符,预计需要花费 8 分钟才能阅读完成。

浏览器中的 HTTP 申请

XMLHttpRequest

XHR 对象用于与服务器交互。通过 XMLHttpRequest 能够在不刷新页面的状况下申请特定 URL,获取数据。
XMLHttpRequestAJAX 编程中被大量应用。

MDN 文档

Fetch

Fetch API 提供了一个获取资源的接口(包含跨域申请)

MDN 文档

AJAX

Asynchronous JavaScript And XML,是一种应用 XMLHttpRequest 技术构建更简单,动静的网页的编程实际。大部分的 ajax 其实就是对 XMLHttpRequest 的相干 API 进行封装,使其应用起来更加不便。

MDN 文档

跨域

跨域,顾名思义,逾越区域。大略意思为拜访的网站申请非同源资源。

因为安全性等问题,浏览器自带同源策略,所谓同源是指域名,协定,端口均雷同。当拜访的网站须要申请非同源资源时,浏览器将回绝这些非同源申请。在这种状况下,咱们须要解决浏览器跨域时拒绝请求非同源资源的限度。

当浏览器呈现跨域时,那就不可避免的引出两个要害的概念了。简略申请 非简略申请

当跨域产生时,非简略申请 会在真正向服务端发送申请前进行 预检申请(OPTIONS),。

简略申请

1、条件定义:若申请满足以下 所有的条件 ,则申请可视为 简略申请

  • 应用下列办法之一:
  • GET
  • HEAD
  • POST
  • 申请首部字段不得超出以下汇合
  • Accept
  • Accept-Language
  • Content-Language
  • Conent-Type:text/plain || multipart/form-data || application/x-www-form-urlencoded
  • DPR
  • Downlink
  • Save-Data
  • Viewport-Width
  • Width
  • 申请中的任意 XMLHttpRequestUpload 对象均没有注册任何事件监听器
  • 申请中没有应用 ReadableStream 对象

非简略申请

1、条件定义:若申请满足下列任一条件时,即应首先发送预检申请(options)。

  • 应用了上面的任一办法:
  • PUT
  • DELETE
  • CONNECT
  • OPTIONS
  • TRACE
  • PATCH
  • 设置了额定的申请首部字段(除去以下汇合中的)
  • Accept
  • Accept-Language
  • Content-Language
  • Conent-Type:text/plain || multipart/form-data || application/x-www-form-urlencoded
  • DPR
  • Downlink
  • Save-Data
  • Viewport-Width
  • Width
  • 申请中的 XMLHttpRequestUpload 对象注册了任意多个事件监听器
  • 申请中应用了 ReadableStream 对象

解决跨域的计划

jsonp

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(...)

维基百科

JSONP 的原理和实现

CORS

Cross Origin Resource Sharing,跨域资源共享,由一系列传输的 HTTP 头组成,这些 HTTP 头决定浏览器是否阻止前端 JavaScript 代码获取跨域申请的响应。

MDN 文档

1、Access-Control-Allow-Origin:批示申请的资源能共享给哪些域

2、Access-Control-Allow-Credentials:批示当申请的凭证标记为 true 时,是否响应该申请

3、Access-Control-Allow-Headers:用在对预申请的响应中,哪些 HTTP 办法容许拜访申请的资源

4、Access-Control-Expose-Headers:批示哪些 HTTP 头的名称能在响应中列出

5、Access-Control-Max-Age:批示预申请的后果能被缓存多久

6、Access-Control-Request-Headers:用于发动一个预申请,告知服务器正式申请会应用哪些 HTTP 头

7、Access-Control-Request-Method:用于发动一个预申请,告知服务器正式申请会应用哪一种 HTTP 申请办法

8、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+ 域名的模式,这样预检申请就不会重定向了。

正文完
 0