Web-解决跨域问题

22 篇文章 0 订阅
4 篇文章 0 订阅

为什么会有跨域问题:

1、什么是跨域

  • 浏览器对于JavaScript的同源策略的限制

2、跨域原因

  • 域名不同:www.jd.com/www.taobao.com
  • 域名相同,端口不同:www.jd.com:8080/www.jd.com:8081
  • 二级域名不同:item.jd.com/miaosha.jd.com
  • 协议不同:http/https
  • 请求路径不同不属于跨域

3、跨域问题

  • 跨域不一定会有跨域问题
  • 跨域问题:浏览器对于ajax请求的一种安全限制,一个页面发起ajax请求,只能与当前域名相同的路径,这样能有效阻止跨站攻击

解决跨域问题的方案:

1、Jsonp

  • 最早的解决方案,利用script标签可以跨域的原理
  • 限制:需要服务的支持 \ 只能发起GET请求

2、nginx反向代理

  • 利用nginx把跨域反向代理为不跨域,支持各种请求方式
  • 限制:需要在nginx进行额外配置,语义不清晰

3、CORS

  • 规范化的跨域请求解决方案,安全可靠
  • 优势:在服务端控制是否跨域,可自定义规则 / 支持各种请求方式
  • 限制:会产生额外的请求

CORS解决跨域问题:

1、什么是CORS

  • W3C标准,全称“跨域资源共享”(Cross-origin resource sharing)
  • 允许浏览器向跨域服务器发起XMLHttpRequest(ajax底层对象)请求,从而克服ajax只能同源使用的限制
  • CORS需要浏览器端与服务器端都支持该功能
  • 浏览器端:目前,所有的浏览器都支持该功能(IE10以下不行),不需要用户参与,浏览器自动完成
  • 服务器端:CORS通信与ajax没有差别,不需要改变业务逻辑。浏览器的请求会带有一些是否允许跨域的头信息,然后响应头中需要加入一些信息,一般通过过滤器完成

2、CORS原理

  • ajax分为两类:简单请求 \ 特殊请求
a、简单请求
  • 同时满足以下两大条件:
    – 请求方法是以下三种方法之一:HEAD \ GET \ POST
    – HTTP头信息不超出以下几种字段:Accept \ Accept-Language \ Content-Language \ Last-Event-ID \ Content-Type(只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain)
  • 当发起简单请求时,会在请求头携带origin字段,会指出当前请求属于哪个域(协议+域名+端口),服务会根据这个值决定是否允许跨域,如果服务端允许跨域,会在响应头中携带下面信息:
    Access-Control-Allow-Origin: http://manage.leyou,com // 可接收的域,是一个具体域名或者*(代表任何域名)
    Access-Control-Allow-Credentials: true // 是否允许携带cookie,默认情况下不会携带
    Content-Type: text/html; charset=utf-8
  • 要想操作cookie解决跨域问题,需满足以下条件:
    – 服务的响应头中需设置允许携带cookie
    – 响应头中的可接收的域一定不能为*,必须指定域名
b、特殊请求
  • 不符合简单请求条件的请求,例如PUT请求
  • 特殊请求会在正式通信之前,增加一次HTTP查阅请求,成为“预检”请求:浏览器询问服务器当前页面所在域名是否在服务器许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定回复,浏览器才会发出正式XMLHttpRequest请求,否则就会报错
  • “预检”请求:
    OPTIONS /cors HTTP/1.1
    Origin: http://manage.leyou.com
    Access-Control-Request-Method: PUT // 接下来会用到的请求方式PUT
    Access-Control-Request-Headers: X-Custom-Header // 额外用到的头信息
    Host: apii.leyou.com
    Accept-Language: en-US
    Connection: keep-alive
    User-Agent: Mozilla/5.0...
  • 预检请求的响应
    HTTP/1.1 200 OK
    Access-Control-Allow-Origin: http://manage.leyou.com // 允许请求
    Access-Control-Allow-Credentials: true // 是否允许携带cookie,默认情况下不会携带
    Access-Control-Allow-Methods: GET,POST,PUT // 允许访问的方式
    Access-Control-Allow-Headers: X-Custom-Header // 允许携带的头信息
    Access-Control-Max-Age: 1728000 // 本次许可的有效时长,单位是秒,过期之前的Ajax请求不需要预检

CORS过滤器实现:

1、建立过滤器对象

  • 在zuul网关微服务创建过滤器配置
  • 使用Java配置类实现
  • 步骤:
    – 创建配置对象
    – 创建配置源
    – 使用配置源作为参数创建过滤器对象
package com.leyou.gateway.config;

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 LeyouCorsFilter {
    @Bean
    public CorsFilter corsFilter(){
        // 初始化cors配置对象
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.addAllowedOrigin("http://manage.leyou.com");  // 允许跨域的域名
        configuration.addAllowedMethod("*");    // 允许所有的请求方法
        configuration.addAllowedHeader("*");    // 允许所有请求头信息
        configuration.setAllowCredentials(true);    // 允许携带cookie
        // 初始化cors配置源对象
        UrlBasedCorsConfigurationSource configurationSource = new UrlBasedCorsConfigurationSource();
        configurationSource.registerCorsConfiguration("/**",configuration);
        // 返回corsfilter实例,参数:cors配置源对象
        return new CorsFilter(configurationSource);
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值