写点什么

【Spring Boot 26】分别在 SpringBoot 和 Vue 中解决跨域问题

用户头像
极客good
关注
发布于: 刚刚

import org.springframework.stereotype.Component;


import javax.servlet.*;


import javax.servlet.http.HttpServletResponse;


import java.io.IOException;


import java.lang.annotation.Annotation;


//拦截器添加跨域支持(如果是 web.xml 配置拦截器,请将 @component 删除)


@Component


public class CORSFilter implements Filter {


@Override


public void init(FilterConfig filterConfig) throws ServletException {


}


@Override


public void doFilter(ServletRequest serv


【一线大厂Java面试题解析+核心总结学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


letRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {


HttpServletResponse response = (HttpServletResponse) servletResponse;


response.setHeader("Access-Control-Allow-Origin", "*");


response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");


response.setHeader("Access-Control-Max-Age", "3600");


response.setHeader("Access-Control-Allow-Headers", "x-requested-with");


filterChain.doFilter(servletRequest, servletResponse);


}


@Override


public void destroy() {


}


}


web.xml 中


<filter>


<filter-name>crossorigin</filter-name>


<filter-class>com.test.test.crossorigin</filter-class>


</filter>


<filter-mapping>


<filter-name>crossorigin</filter-name>


<url-pattern>/*</url-pattern>


</filter-mapping>

4、JSONP 实现(仅适用于 GET 请求,不推荐使用,详细请见六前端中跨域的解决方法)

5、注解实现

(1)从 Spring MVC 4.2 开始增加支持跨域访问。


在方法或类上增加 @CrossOrigin 注解。


其中 @CrossOrigin 中的 2 个参数:


  1. origins??: 允许可访问的域列表

  2. ?maxAge:飞行前响应的缓存持续时间的最大年龄(以秒为单位)。


(2)自定义规则支持全局跨域访问


在 spring-mvc.xml 文件中配置映射路径,如下:


mvc:cors


<mvc:mapping path="/cross/*"/>


</mvc:cors>


如果整个项目所有方法都可以访问,则可以这样配置


mvc:cors


<mvc:mapping path="/**"/>


</mvc:cors>


其中* 表示匹配到下一层


** 表示后面不管有多少层,都能匹配。

6、nginx 实现

五、前端中跨域的解决方法



1、设置 document.domain 解决无法读取非同源网页的 cookie 问题

因为浏览器是通过 document.domain 属性来检查两个网页是否同源,因此只要通过设置相同的 document.domain,两个网页就可以共享 cookie(此方案仅限主域相同,子域不同的跨域应用场景。)


// 两个页面都设置


document.domain = 'test.com';

2、跨文档通信 API:window.postMessage()

调用 postMessage 方法实现父窗口http://test1.com向子窗口http://test2.com发消息(子窗口同样可以通过该方法发送消息给父窗口)


它可以用于解决以下方面的问题:


  1. 页面和其打开的新窗口的数据传递

  2. 多窗口之间消息传递

  3. 页面与嵌套的 iframe 消息传递

  4. 上面三个场景的跨域数据传递


// 父窗口打开一个子窗口


var openWindow = window.open('http://test2.com', 'title');


// 父窗口向子窗口发消息(第一个参数代表发送的内容,第二个参数代表接收消息窗口的 url)


openWindow.postMessage('Nice to meet you!', 'http://test2.com');


调用 message 事件,监听对方发送的消息


// 监听 message 消息


window.addEventListener('message', function (e) {


console.log(e.source); // e.source 发送消息的窗口


console.log(e.origin); // e.origin 消息发向的网址


console.log(e.data); // e.data 发送的消息


},false);

3、JSONP

JSONP 是服务器与客户端跨源通信的常用方法。


最大特点就是简单,兼容性好,缺点是只支持 get 请求,不支持 post 请求。


核心思想:网页通过添加一个<script>元素,向服务器请求 JSON 数据,服务器收到请求后,将数据放在一个指定名称的回调函数的参数位置传回来。


①原生实现


<script src="http://test.com/data.php?callback=dosomething"></script>


// 向服务器 test.com 发出请求,该请求的查询字符串有一个 callback 参数,用来指定回调函数的名字


// 处理服务器返回回调函数的数据


<script type="text/javascript">


function dosomething(res){


// 处理获得的数据


console.log(res.data)


}


</script>


②jQuery ajax


$.ajax({


url: 'http://www.test.com:8080/login',


type: 'get',


dataType: 'jsonp', // 请求方式为 jsonp


jsonpCallback: "handleCallback", // 自定义回调函数名


data: {}


});


③Vue.js


this.$http.jsonp('http://www.domain2.com:8080/login', {


params: {},


jsonp: 'handleCallback'


}).then((res) => {


console.log(res);


})

4、CORS

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


  1. 普通跨域请求:只需服务器端设置 Access-Control-Allow-Origin

  2. 带 cookie 跨域请求:前后端都需要进行设置


【前端设置】根据 xhr.withCredentials 字段判断是否带有 cookie


(1)原生 AJAX


var xhr = new XMLHttpRequest(); // IE8/9 需用 window.XDomainRequest 兼容


// 前端设置是否带 cookie


xhr.withCredentials = true;


xhr.open('post', 'http://www.domain2.com:8080/login', true);


xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');


xhr.send('user=admin');


xhr.onreadystatechange = function() {


if (xhr.readyState == 4 && xhr.status == 200) {


alert(xhr.responseText);


}


};


②jQuery ajax?


$.ajax({


url: 'http://www.test.com:8080/login',


type: 'get',


data: {},


xhrFields: {


withCredentials: true // 前端设置是否带 cookie


},


crossDomain: true, // 会让请求头中包含跨域的额外信息,但不会含 cookie


});


③vue-resource


Vue.http.options.credentials = true


④ axios?


axios.defaults.withCredentials = true


【服务端设置】


服务端对于 CORS 的支持,主要是通过设置 Access-Control-Allow-Origin 来进行的。如果浏览器检测到相应的设置,就可以允许 ajax 进行跨域访问。


① Java 后台


/*


  • 导入包:import javax.servlet.http.HttpServletResponse;

  • 接口参数中定义:HttpServletResponse response


*/


// 允许跨域访问的域名:若有端口需写全(协议+域名+端口),若没有端口末尾不用加'/'


response.setHeader("Access-Control-Allow-Origin", "http://www.domain1.com");


// 允许前端带认证 cookie:启用此项后,上面的域名不能为'*',必须指定具体的域名,否则浏览器会提示


response.setHeader("Access-Control-Allow-Credentials", "true");


// 提示 OPTIONS 预检时,后端需要设置的两个常用自定义头


response.setHeader("Access-Control-Allow-Headers", "Content-Type,X-Requested-With");


② Nodejs 后台


var http = require('http');


var server = http.createServer();


var qs = require('querystring');

用户头像

极客good

关注

还未添加个人签名 2021.03.18 加入

还未添加个人简介

评论

发布
暂无评论
【Spring Boot 26】分别在SpringBoot和Vue中解决跨域问题