前后端之跨域请求解决

前后端分离之跨域请求及cookie接收发送

解决思路:

使用CORS解决不同源前后端之间数据访问,和cookies-session共享(即允许前端在发送请求的时候带上本域名下的cookie访问另一个域名下的后端服务器,后端服务器允许指定域名发送cookie和接收cookie).要想实现前后端跨域,不管是在前端还是在后端都必须进行配置

什么是CORS

CORS是一个w3c标准,全称是"跨域资源共享"(Cross-origin resource sharing),但一个请求url的协议,域名,端口三者之间任意与当前页面地址不同即为跨域.它允许阅览器向跨源服务器发送XMLHttpRequest请求,从而客服AJAX只能同源使用的限制.
浏览器默认的安全限制为同源策略,即JavaScript或Cookie只能访问同源(相同协议,相同域名,相同端口)下的内容。但由于跨域访问资源需要,出现了CORS机制,这种机制让web服务器能跨站访问控制,使跨站数据传输更安全。CORS需要阅览器和服务器同时支持,目前,主流的浏览器都支持cors。

CORS的2种请求方式
  1. 简单请求
(1) 请求方法是以下三种方法之一:
        HEAD
        GET
        POST
(2)HTTP的头信息不超出以下几种字段:
        Accept
        Accept-Language
        Content-Language
        Last-Event-ID
        Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

不同时满足上面两个条件,就是非简单请求,简单请求
当进行跨域请求的时候,浏览器会自动在请求中添加Origin头部(值为:请求域名),表示这个请求是一个跨域请求
在这里插入图片描述
2. 非简单请求
不满足简单请求的条件就是非简单请求.
非简单请求相比于简单请求,需要在请求前主动请求一次Http查询请求,又称预检请求。
浏览器先请求服务器,当前网页所在域名是否在服务器许可名单中以及可以使用那些HTTP动词和头信息字段,当客户端得到肯定答复时,浏览器才会正式发出正式请求。
预检请求用的请求方法是OPTIONS,表示这个请求是用来询问的。
当服务其收到预检请求后,检查了Origin,Access-Control-Request-Method等信息字段后,如果没有问题,则确认允许跨源请求,就可以做出了回应。
在这里插入图片描述
上图为预检请求后返回的头部信息,详细说明服务器允许那些域名允许跨域,浏览器接收之后解除跨域访问限制

服务器端跨域处理流程

	1. 首先查看http头部有无origin字段;
	2. 如果没有,或者不允许,当成普通请求;
	3. 如果有且是允许的,再看是否是preflight(method=OPTIONS);
	4. 如果不是preflight(简单请求),返回Allow-Origin,Allow-Credential等字段,并返回正常内容;
	5. 如果是preflight(非简单请求),返回Allow-Headers,Allow-Methods等;
解决跨域的代码实现
1. 后端配置代码

这里使用的是springmvc拦截器,对所有服务端的响应添加头部信息

// 拦截器类
public class CrossdomainInterceptor implements HandlerInterceptor {

    // 在执行Controller方法之后执行
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }
    // 在执行Controller方法前执行
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpServletResponse resp = (HttpServletResponse) response;
        HttpServletRequest rep = (HttpServletRequest) request;

        // 设置允许跨域的网站域名
        resp.addHeader("Access-Control-Allow-Origin", rep.getHeader("Origin"));
        // 允许跨域请求中携带cookie
        resp.addHeader("Access-Control-Allow-Credentials", "true");
        // 如果存在自定义的header参数,需要在此处添加,逗号分隔,允许跨域时带上的自定义头部
        resp.addHeader("Access-Control-Allow-Headers", "authorization,Origin, No-Cache, X-Requested-With, "
                + "If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, " + "Content-Type, X-E4M-With");
        // 允许的跨域请求方法
        resp.addHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS,DELETE,PUT,");
        // 测试拦截器是否执行
        System.out.println("拦截器执行");
        return true;
    }
}

springmvc.xml 配置文件

    <mvc:interceptors>
        <!--第一个拦截器-->
        <mvc:interceptor>
            <!--要拦截的Controller方法-->
            <!--<mvc:mapping path="/**"/>表示所有方法都拦截-->
            <!--<mvc:mapping path="/users/*"/>表示只拦截users下的路径-->
            <mvc:mapping path="/**"/>

            <bean class="cn.luntan.ssm.interceptor.CrossdomainInterceptor"></bean>
            <!--表示不拦截那个地址-->
            <!-- <mvc:exclude-mapping path=""/>-->
        </mvc:interceptor>
    </mvc:interceptors>
2. 前端配置代码

前端使用vue脚手架

// 在main.js中添加如下代码,作用是允许请求时携带本域cookie和接收不同源服务器发送的cookie
axios.defaults.withCredentials=true;

jquery ajax解决跨域发送cookie

 $.ajax({
                    type: 'post',
                    url: "http://localhost:8080/post/secondcom",
                    data: JSON.stringify(data),
                    // dataType: 'jsonp',
                    
                    
                    xhrFields: {
                        withCredentials: true
                    },
                    crossDomain: true,


                    contentType: "application/json",
                    success: function (data) {
                        if (data) {
                            alert("评论成功");
                        } else {
                            alert("评论失败")
                        }
                    }
                })
将代码加入之后就可以前后端的资源访问了,快去试试吧
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值