Cors跨域请求

 

为什么要设置跨域请求?

一个界面发起的ajax请求,只能是当前页面同域名发起的,这样就可以有效避免黑客发起的对服务器的恶意攻击;

请求跨域了,那么请求到底发出去没有?

跨域并不是请求发不出去,请求能发出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了。你可能会疑问明明通过表单的方式可以发起跨域请求,为什么 Ajax 就不会?因为归根结底,跨域是为了阻止用户读取到另一个域名下的内容,Ajax 可以获取响应,浏览器认为这不安全,所以拦截了响应。但是表单并不会获取新的内容,所以可以发起跨域请求。同时也说明了跨域并不能完全阻止 CSRF,因为请求毕竟是发出去了。

 

常用的跨域问题的解决方式?

一,nginx : 

a网站向b网站请求1.js文件时,向b网站发送一个获取的请求,nginx根据配置文件接收这个请求,代替a网站向b网站来请求这个资源,nginx拿到这个资源后再返回给a网站,以此来解决了跨域问题。

 

例子:

server {
        #监听8000端口
        listen       8000;
        #监听指定的ip地址
        server_name  10.10.2.116;
        #对对应url路径执行反向代理,如10.10.2.116:8000/demo
        location /demo {
        #目标的ip地址
            proxy_pass http://www.leyou.com; 
        }
}

缺点: 需要的nginx进行额外配置;

二,CORS:

规范的跨域请求解决方案,安全可靠:

优点: 在服务端进行控制是否允许跨域,可以自定义规则,如header,method,origin,自定义限制;

缺点: 会产生额外的请求;

简单请求和和复杂请求的区分:

1.请求方式的区分:head,put,post;

2.头信息的限制:

Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值  application/x-www-form-urlencoded、multipart/form-data、text/plain

 

发送简单请求时 浏览器会自动识别并携带字段 origin =www.leyou.com,服务器会根据这个值进行判定是否允许跨域

不满足简单请求条件则就是复杂请求

 

CORS跨域请求的原理:

浏览器想服务端发送预检请求:

OPTIONS /cors HTTP/1.1
Origin: http://manage.leyou.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header
Host: api.leyou.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...

服务端收到预检请求后,如果允许跨域,会发出响应:

HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2.0.61 (Unix)
Access-Control-Allow-Origin: http://manage.leyou.com
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header
Access-Control-Max-Age: 1728000
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Content-Length: 0
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain

服务端返回自己对跨域的请求的要求限制:

- Access-Control-Allow-Origin:可接受的域,是一个具体域名或者*,代表任意
- Access-Control-Allow-Methods:允许访问的方式
- Access-Control-Allow-Headers:允许携带的头
- Access-Control-Max-Age:本次许可的有效时长,单位是秒


允许客户端可以携带Cookie
- Access-Control-Allow-Credentials:是否允许携带cookie,默认情况下,cors不会携带cookie,除非这个值是true

 

客户端跨域想要携带COOKIE要满足的要求:

- 服务的响应头中需要携带Access-Control-Allow-Credentials并且为true。
- 浏览器发起ajax需要指定withCredentials 为true
- 响应头中的Access-Control-Allow-Origin一定不能为*,必须是指定的域名

 

实际操作:

  1. 需要的配置一个Bean ,CorsFilter  过滤类 包含
    UrlBasedCorsConfigurationSource----》 1.path:对映射路径的限制   2.CorsConfiguration---》封装了对跨域请求的限制,origin,header,method的设置;
  2. CorConfiguration 封装对跨域请求的限制:

 

允许的域,不要写*,否则cookie就无法使用了

        config.addAllowedOrigin("http://manage.leyou.com");
        config.addAllowedOrigin("http://www.leyou.com");
允许的请求方式
        config.addAllowedMethod("OPTIONS");
        config.addAllowedMethod("HEAD");
        config.addAllowedMethod("GET");
        config.addAllowedMethod("PUT");
        config.addAllowedMethod("POST");
        config.addAllowedMethod("DELETE");
        config.addAllowedMethod("PATCH");
允许的头信息
        config.addAllowedHeader("*");
是否发送Cookie信息
        config.setAllowCredentials(true);
添加映射路径,我们拦截一切请求
        UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
        configSource.registerCorsConfiguration("/**", config);
   
返回新的CorsFilter.
        return new CorsFilter(configSource);

 


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class GlobalCorsConfig {
    @Bean
    public CorsFilter corsFilter() {
        //1.添加CORS配置信息
        CorsConfiguration config = new CorsConfiguration();

        //1) 允许的域,不要写*,否则cookie就无法使用了
        config.addAllowedOrigin("http://manage.leyou.com");
        config.addAllowedOrigin("http://www.leyou.com");
        //2) 是否发送Cookie信息
        config.setAllowCredentials(true);
        //3) 允许的请求方式
        config.addAllowedMethod("OPTIONS");
        config.addAllowedMethod("HEAD");
        config.addAllowedMethod("GET");
        config.addAllowedMethod("PUT");
        config.addAllowedMethod("POST");
        config.addAllowedMethod("DELETE");
        config.addAllowedMethod("PATCH");
        // 4)允许的头信息
        config.addAllowedHeader("*");

        //2.添加映射路径,我们拦截一切请求
        UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
        configSource.registerCorsConfiguration("/**", config);

        //3.返回新的CorsFilter.
        return new CorsFilter(configSource);
    }
}

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值