ssm项目开发过程中跨域问题解决

在写这学期课设时,页面没有采用jsp,前端是对床在他本子上写的,我提供了url给他,他的ajax请求后后台却返回了403,但是这时候我写的jsp测试却没有问题,开始怀疑是表单提交和ajax提交的请求类别不同,于是在网上搜,果然找到了一些线索:

    当请求方法不是GET\POST\HEAD之一或者请求类型不是application/x-www-form-urlencoded、multipart/form-data、text/plain之一时,请求就是复杂请求
    而ajax请求的类型是application/json,也就是json。这时的请求自然就是复杂请求了,至于复杂请求到底复杂在哪了,我猜是不是因为json结构可以很复杂。
    这就涉及到安全问题了,为了安全同源策略规定浏览器对跨域的请求有不同的处理:
    如果是跨域的简单请求则浏览器在请求头中加上Origin头后直接发送,Origin对应的值为请求方的域名。服务器发现请求头中有Origin字段,就会验证对应域名是否是被允许的,然后进行相应处理。**
    如果是复杂请求,则浏览器会先发一个预检请求,类型为OPTIONS,询问服务器是否该域名被允许发送请求,如果允许,则浏览器收到回应后,会发送真正的请求,这一切对用户而言都是隐藏的。
    服务器对跨域请求的响应头中有以下内容:
    Access-Control-Allow-Origin:服务器允许跨域请求的域名
    Access-Control-Expose-Headers:允许返回给跨域请求的响应头列表
    Access-Control-Max-Age:预检请求返回的结果的有效时间,有效时间内浏览器不用再次向服务器发送预检请求
    Access-Control-Allow-Credentials:告知浏览器当withCredentials属性设置为true时,是否可以显示跨域请求返回的内容。简单请求时,浏览器会根据此响应头决定是否显示响应的内容。预先验证请求时,浏览器会根据此响应头决定在发送实际跨域请求时,是否携带认证信息。
    Access-Control-Allow-Methods:服务端支持的请求方法
    Access-Control-Allow-Headers:服务端支持的请求头

知道了这些,那问题就容易解决了,我们可以在后台设置一个拦截器,拦截带有Origin字段的请求头,并给响应头中加入那些字段,设置为相应的值。

package gh.ttms.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class OptionsInterceptor implements HandlerInterceptor {
    //private List<String> excludedUrls;

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        if (httpServletRequest.getHeader("Origin")!=null){
            httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
            httpServletResponse.setHeader("Access-Control-Allow-Methods", "*");
            httpServletResponse.setHeader("Access-Control-Max-Age", "3600");
            httpServletResponse.setHeader("Access-Control-Allow-Headers",
                    "Origin, X-Requested-With, Content-Type, Accept");
            
        }
        
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }

//    public List<String> getExcludedUrls() {
//        return excludedUrls;
//    }
//
//    public void setExcludedUrls(List<String> excludedUrls) {
//        this.excludedUrls = excludedUrls;
//    }

}

tips:

    这里有一个小问题就是如果设置了Access-Control-Allow-Credentials为true,则Access-Control-Allow-Origin不能设为*
    跨域就是不同域之间的交互,域名不同或域名相同端口不同等都属于不同域,更多请自行百度
    网上有说配置<mvc:cros/>的,但是这个好像对复杂请求没啥用,可能是因为对复杂请求浏览器会发送预检请求吧
    我还试过直接针对OPTIONS类型的请求写了个Controller,如下,作用是给响应头中加那些字段,最后记得字段加进去了但跨域请求还是403,目前还不知道为啥

package gh.ttms.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpServletResponse;

@Controller
public class OptionsInterceptor {

    @RequestMapping(value = "/**",method = RequestMethod.OPTIONS)
    public void handler(HttpServletResponse response)
    {
        response.setHeader("Access-Control-Allow-Origin","*");
        response.setHeader("Access-Control-Allow-Methods","*");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers",
                "Origin, X-Requested-With, Content-Type, Accept");

    }
}

参考:::

https://blog.csdn.net/qqHJQS/article/details/52368793

https://blog.csdn.net/qq_34968945/article/details/86314290

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值