erlang的 cowboy服务解决跨域问题

 

    对于非简单请求(具体可以这篇文章,跨域资源共享),在正式访问请求前,浏览器会发送一个预检请求,就是option请求。针对option请求,必须保证如下2点,后面的正式请求才会访问:第一,要能返回Access-Control-Allow-Origin 等字段,告诉浏览器你这个请求域名我服务端是可以支持的。第二,对于跨域的预检请求,要能返回成功。

由于浏览器的同源策略,前后端分离的时候会出现跨域的问题

1、什么就算跨域了,以下三点中只要有一个不同就是跨域啦。

1)、协议不同;2)、域名不同(IP地址不同)、3)、端口号不同

下图来自百度百科

因为浏览器的同源策略限制,不是同源的脚本不能操作其他源下面的资源,想操作另一个源下面的资源就属于跨域了,这里说的跨域是广义跨域,我们常说的代码中请求跨域,是狭义的跨域,即在脚本代码中向非同源域发送http请求

浏览器的同源策略(SOP/same origin policy)是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS(跨站脚本攻击 cross site scripting)和CSRF(跨站请求伪造cross-site request forgery)等攻击。

(同源 origin:协议,域名,端口号,不清楚的话,直接在浏览器控制台中输入window.location.origin看看返回值就知道了。)

下面两种情况,是不受跨域限制的,严格来讲,这两种情况只是跨站资源请求:

  1)页面中的链接,重定向及表单提交是不受同源策略限制的

  2)跨域资源的引入,如<script src=""> <image src=""> <iframe>等

 

跨域问题, 前端跨域请求,cors errors

详情解释文档   https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS/Errors

如果未正确设置CORS配置,浏览器控制台将显示错误,例如"Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at $somesite"(跨源请求已阻止:同源策略禁止在某些站点上读取远程资源”),表示请求因违反CORS安全性而被阻止规则。 但这可能不一定是设置错误。 因为用户的Web应用程序和远程外部服务可能故意禁止该请求。如果要使端点可用,则需要进行一些调试才能成功。

后端没有配置Response的header头的access-control-allow-origin 参数,

 

在cowboy的处理函数中对header作如下处理:

    Req1 = cowboy_req:set_resp_header(<<"access-control-allow-origin">>, <<$*>>, Req0),

    Req2 = cowboy_req:set_resp_header(<<"access-control-allow-methods">>, <<"POST">>, Req1),

    Req3 = cowboy_req:set_resp_header(<<"access-control-allow-headers">>, <<"content-type">>, Req2)

 

这个设置可以设置在Req的接收的地方:然后后面的Req都是带着“access-control-allow-origin"参数的,也可以设置在返回req的地方。

 

 

看看java是如何解决跨域请求问题的: 

1. 

// 最简单的处理方式
response.setHeader("Access-Control-Allow-Origin","*");

2.

复制代码
// 这个可以用过滤器统一处理
if (request.getHeader("Access-Control-Request-Method") != null && "OPTIONS".equals(request.getMethod())) {
            // CORS "pre-flight" request
            response.addHeader("Access-Control-Allow-Origin", "*");
            response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
            response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
            response.addHeader("Access-Control-Max-Age", "1800");//30 min
        }
复制代码

3.使用拦截器统一做跨域处理

复制代码
@Component
public class CORSInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //添加跨域CORS
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Headers", "X-Requested-With,content-type,token");
        response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH");
        return true;
    }
}
复制代码

4.最后启用拦截器就ok,以下展示在Spring-boot配置

复制代码
public class WebConfigTest extends WebMvcConfigurerAdapter {
    @Autowired
    private CORSInterceptor corsInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(corsInterceptor);
    }
}
复制代码
posted @ 2020-06-09 11:20  孤独信徒  阅读(656)  评论(0编辑  收藏  举报