028-跨域

作者: 郭艺宾 | 来源:发表于2018-07-03 19:18 被阅读6次

什么是跨域

跨域,指的是浏览器不能让XmlHttpRequest对象(ajax)执行其他网站的脚本。

它是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制。

所谓同源是指,域名,协议,端口均相同,举个栗子:

http://www.123.com/index.html  调用  http://www.123.com/server.PHP (非跨域)

http://www.123.com/index.html  调用  http://www.456.com/server.php  主域名不同:123/456,跨域)

http://abc.123.com/index.html  调用  http://def.123.com/server.php  (子域名不同:abc/def,跨域)

http://www.123.com:8080/index.html  调用  http://www.123.com:8081/server.php  (端口不同:8080/8081,跨域)

http://www.123.com/index.html   调用 https://www.123.com/server.php   (协议不同:http/https,跨域)

请注意:localhost和127.0.0.1虽然都指向本机,但也属于跨域。

浏览器执行javascript脚本时,会检查这个脚本属于哪个页面,如果不是同源页面,就不会被执行。

如何解决跨域

方法1:JSONP

虽然浏览器的同源策略不能让XmlHttpRequest对象之间访问其他域的资源,但是当需要通讯时,本站脚本创建一个并提供一个回调函数来接收数据(函数名可约定,或通过地址参数传递)。

第三方API产生的响应为json数据的包装(故称之为jsonp,即json padding),形如:    

callback({"name":"hax","gender":"Male"})    这样浏览器能通过。

此种方式最大的优点就是几乎所有浏览器都支持,兼容性好,但它只能处理GET请求。为什么?

因为没有这种搞法呀!

<script src="http://xxx.com/api" method="post"/> 。

方法2:CORS

CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。

它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。

CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。

整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。

浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。

因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

CORS具体流程:

对于简单请求,浏览器直接发出CORS请求。具体来说,就是在头信息之中,增加一个Origin字段。

下面是一个例子,浏览器发现这次跨源AJAX请求是简单请求,就自动在头信息之中,添加一个Origin字段。

GET /cors HTTP/1.1

Origin: http://api.bob.com

Host: api.alice.com

Accept-Language: en-US

Connection: keep-alive

User-Agent: Mozilla/5.0

上面的头信息中,Origin字段用来说明,本次请求来自哪个源(协议 + 域名 + 端口)。

服务器根据Origin指定的域名判断是否要接受这个请求。

如果Origin指定的源,不在许可范围内,服务器会返回一个正常的HTTP回应。浏览器发现,这个回应的头信息没有包含Access-Control-Allow-Origin字段,就知道出错了,从而抛出一个错误,被XMLHttpRequest的onerror回调函数捕获。

注意,这种错误无法通过状态码识别,因为HTTP回应的状态码有可能是200。

服务器如果接受此origin,在处理请求后返回的响应中要添加CORS标准中指定的请求头,多出几个头信息字段。

Access-Control-Allow-Origin: http://api.bob.com

Access-Control-Allow-Credentials: true

Access-Control-Expose-Headers: FooBar

Content-Type: text/html; charset=utf-8

上面的头信息之中,有三个与CORS请求相关的字段,都以Access-Control-开头。

(1)Access-Control-Allow-Origin

该字段是必须的。它的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。

(2)Access-Control-Allow-Credentials

该字段可选。它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。

(3)Access-Control-Expose-Headers

该字段可选。CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:

Cache-Control

Content-Language

Content-Type

Expires

Last-Modified

Pragma

如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。

上面的例子指定,getResponseHeader('FooBar')可以返回FooBar字段的值。

springboot实现跨域cors

增加一个配置类

上面几行代码简单的在服务器端解决了跨域问题。

参考文章:https://www.jianshu.com/p/868a9e53c6bc,https://mp.weixin.qq.com/s/9Jr_nRNY0jCG8-4zh1YXAQ

代码地址: https://gitee.com/blueses/spring-boot-demo

相关文章

  • 028-跨域

    什么是跨域 跨域,指的是浏览器不能让XmlHttpRequest对象(ajax)执行其他网站的脚本。 它是由浏览器...

  • 深入跨域问题(3) - 利用 JSONP 解决跨域

    深入跨域问题(1) - 初识 CORS 跨域资源共享;深入跨域问题(2) - 利用 CORS 解决跨域深入跨域问题...

  • 关于设置env等环境变量的思考

    1、如何处理跨域后台处理跨域前端处理跨域浏览器处理跨域 前端本地处理跨域:代理线上跨域的处理方式:Nginx反向代...

  • Web前后端跨域问题处理

    跨域问题有前台跨域(iframe间)和后台跨域。 前台跨域的解决方案可以采用跨域文档通讯(Cross domain...

  • 跨域

    跨域 什么是跨域: 解决跨域 通过jsonp原理:在页面引入跨域js和css时,没有存在跨域问题.因此可以动态创建...

  • 跨域问题详解分析

    参考文档 CORS详解 跨域资源共享 CORS 详解 js中几种实用的跨域方法原理详解 跨域的那些事儿 跨域与跨域...

  • 跨域问题:好几种解决方案

    跨域分为广义跨域和狭义跨域 广义跨域:一个域下的文档或脚本试图去请求另一个域下的资源; 广义跨域可以分为以下几种:...

  • ajax readystatus=0;status=0 报错

    跨域 跨域 跨域 一定要找运维或者后台解决

  • 深入跨域问题(2) - 利用 CORS 解决跨域

    阅读目录: 深入跨域问题(1) - 初识 CORS 跨域资源共享;深入跨域问题(2) - 利用 CORS 解决跨域...

  • 响应头设置跨域和Spring注解跨域

    CORS跨域原理详解Spring解决跨域 响应头设置跨域 Spring注解跨域@CrossOrigin 可添加到方...

网友评论

    本文标题:028-跨域

    本文链接:https://www.haomeiwen.com/subject/bkbjuftx.html