跨域的原理及解决方案

简介: 同源策略是Web应用程序安全性模型中的重要概念。根据该策略,Web浏览器允许第一个网页中包含的脚本访问第二个网页中的数据,但前提是两个网页具有相同的来源。来源由URI,主机名和端口号的组合定义。此策略可防止一个页面上的恶意脚本通过该页面的DOM(Document Object Model)获得对另一网页上敏感数据的访问。JSONP由于同源策略,一般来说位于server1.example.com...

跨域限制访问,即为浏览器禁止访问其他网站的资源,是浏览器的限制。如果缺少了同源策略,网页很容易受到XSS、CSFR等攻击。

同源策略是Web应用程序安全性模型中的重要概念。根据该策略,Web浏览器允许第一个网页中包含的脚本访问第二个网页中的数据,但前提是两个网页具有相同的来源。来源由URI,主机名(hostname) 和端口号(port) 的组合定义。此策略可防止一个页面上的恶意脚本通过该页面的DOM(Document Object Model)获得对另一网页上敏感数据的访问。

跨域场景

当一个请求 URL 的协议域名端口三者之间任意一个与当前页面 URL 不同即为跨域

当前页面URL 请求页面URL 是否跨域 原因
http://www.test.com/ http://www.test.com/index.html 同源(协议、域名、端口号相同)
http://www.test.com/ https://www.test.com/index.html 协议不同(http/https)
http://www.test.com/ http://www.baidu.com/ 主域名不同(test/baidu)
http://www.test.com/ http://blog.test.com/ 子域名不同(www/blog)
http://www.test.com:8080/ http://www.test.com:8081/ 端口号不同

跨域解决方案

JSONP

由于同源策略,一般来说网页无法跨域请求资源,而 HTML 的 <script>元素是一个例外。利用<script>元素的这个开放策略,网页可以得到从其他来源动态产生的JSON数据,而这种使用模式就是所谓的 JSONP。用JSONP抓到的数据并不是JSON,而是任意的JavaScript,用 JavaScript 解释器运行而不是用 JSON 解析器解析。

JSONP优点是简单兼容性好,可用于解决主流浏览器的跨域数据访问的问题。缺点是仅支持 get 方法,具有局限性;且可能会遭受 XSS 攻击。

CORS

CORS 是跨域资源分享(Cross-Origin Resource Sharing)的缩写。它是 W3C 标准,属于跨源 AJAX 请求的根本解决方法。

  • Access-Control-Allow-Origin 设置允许请求的域名,多个域名以逗号分隔
  • Access-Control-Allow-Methods 设置允许请求的方法,多个方法以逗号分隔
  • Access-Control-Allow-Headers 设置允许请求自定义的请求头字段,多个字段以逗号分隔
  • Access-Control-Allow-Credentials 设置是否允许发送 Cookies

常用的跨域配置只需设置 Access-Control-Allow-Origin,推荐设置为对应域名。但当使用 Cookies 时,还需要配置Access-Control-Allow-Credentialstrue,且此时Access-Control-Allow-Origin 的配置不能为*,而必须配置为具体的域名。

Java 跨域实现方案

JSONP

Spring 4 ~ Spring 5 低版本中支持全局Jsonp。在 Spring 5 高版本中弃用,且标注建议使用@CrossOrigin

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.AbstractJsonpResponseBodyAdvice;

/**
*
* 统一支持 jsonp 的配置输出
* 使用说明:@RequestMapping 中指定 produces 为 application/json;charset=UTF-8 即可
* 例子:@RequestMapping(path = "/signin", produces = "application/json;charset=UTF-8")
*
*/
@ControllerAdvice(basePackages = {
   "com.yy.ent.union.zone.controller"})
public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice {
   
    public JsonpAdvice() {
   
        super("callback", "jsonpcb");
    }
}

@CrossOrigin

使用@CrossOrigin注解时,推荐指定域名,避免使用*的默认配置,产生不安全的隐患

@RestController
@CrossOrigin(origins = "*")
public class TestController {
   }

当需要使用Cookies时,要配置allowCredentials参数,使用时必须指定具体的域

@CrossOrigin(origins = "http://www.test.com/", allowCredentials = "true")

参考资料:

  1. 什么是跨域?跨域解决方法
相关实践学习
基于函数计算快速搭建Hexo博客系统
本场景介绍如何使用阿里云函数计算服务命令行工具快速搭建一个Hexo博客。
相关文章
|
4月前
|
前端开发 JavaScript 安全
跨域的五种最常见解决方案
跨域的五种最常见解决方案
|
6月前
|
Web App开发 JSON 前端开发
前端跨域解决方案-汇总
前端跨域解决方案-汇总
77 0
|
9月前
|
移动开发 前端开发 JavaScript
前端跨域的解决方案?
前端跨域的解决方案?
73 0
|
4月前
|
Web App开发 JavaScript 前端开发
深入理解前端跨域方法和原理
深入理解前端跨域方法和原理
|
9月前
|
移动开发 前端开发 安全
【前端跨域的解决方案?】
【前端跨域的解决方案?】
|
10月前
|
缓存 前端开发 JavaScript
跨域问题详解及解决方案
跨域问题详解及解决方案
409 0
|
移动开发 JavaScript 前端开发
前端常见跨域解决方案(全)
前端常见跨域解决方案(全)
750 0
|
Web App开发 前端开发 JavaScript
前端跨域解决方案
前后端分离开发给我带来很多的便利,无论是前端同学还是后端同学对于此种开发方式都是举双手赞成的。因为这样我们后端同学不用被css js这一大堆的前端代码折磨了,前端也不用改个样式要开个后台服务。虽然如此方便,但对于前端还是有些问题需要解决的。比如跨域问题,今天在项目中本地局域网测试移动端,手机浏览器打开会出现跨域(pc端跨域已通过chrome设置解决了)。
|
Web App开发 移动开发 JSON
解决跨域问题的8种方案(最新最全)
解决跨域问题的8种方案(最新最全)
346 0
|
JSON JavaScript 前端开发
跨域的原因以及解决方案
跨域的原因以及解决方案
跨域的原因以及解决方案