你又遇到跨域问题了吗

如果前后端不分离,是不是就不会有跨域问题呢?😭

一、同源策略

同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

\color{#FF0000}{同源策略是浏览器的行为} ,是为了保护本地数据不被JavaScript代码获取回来的数据污染,因此拦截的是客户端发出的请求回来的数据接收,即请求发送了,\color{#FF0000}{服务器响应了} ,但是无法被浏览器接收。

我们在简书首页请求百度,可以发现跨域的报错blocked by CORS policy

fetch(new Request('https://www.baidu.com', {
    method: 'POST',
    headers: {},
    body: "param1=value1&param2=value2"
})).then((resp) => { console.log(resp) })
跨域报错

同源策略,它是由Netscape提出的一个著名的安全策略。只有当 protocol(协议)、domain(域名)、port(端口)三者一致时才是同源,后面的请求路径、请求参数、锚点可以不一致。

二、跨域资源共享(CORS)

当我们在响应头中添加了允许跨域header,浏览器就不会拒绝请求了。

  • Access-Control-Allow-Origin: 允许哪些ip或域名可以跨域访问
  • Access-Control-Max-Age: 表示在多少秒之内不需要重复校验该请求的跨域访问权限
  • Access-Control-Allow-Methods: 表示允许跨域请求的HTTP方法,如:GET,POST,PUT,DELETE
  • Access-Control-Allow-Headers: 表示访问请求中允许携带哪些Header信息,如:Accept、Accept-Language、Content-Language、Content-Type

三、实际如何解决跨域问题

1、在前端服务解决跨域

1.1 html标签

虽然浏览器对于不符合同源策略的访问是禁止的,但是仍然存在例外的情况,如以下资源引用的标签不受同源策略的限制:

  • html的script标签
  • html的link标签
  • html的img标签
  • html的iframe标签
1.2 JSONP

JSONP 主要就是利用了 script 标签没有跨域限制的这个特性来完成的。浏览器是允许像 link、img、script 标签在路径上加载一些内容进行请求,是允许跨域的,JSONP 的实现原理就是在 script 标签里面加载了一个链接,去访问服务器的某个请求。但是,\color{#FF0000}{JSONP 有一个限制就是只支持 GET 请求},实际应用中并不推荐。

2、在后端服务解决跨域

2.1 设置HttpServletResponse响应请求头(局部跨域配置)

这是最原始也是最基础的方法。

    @RequestMapping("/cors")
    @ResponseBody
    public String cors(HttpServletResponse response){
        //使用HttpServletResponse定义HTTP返回请求头
        response.addHeader("Access-Control-Allow-Origin", "http://localhost:8080");
        return "cors";
    }
2.2 使用CrossOrigin注解(局部跨域配置)

利用SpringMvc提供的CrossOrigin注解,原理同上,只是利用注解切面的方式实现。

    @RequestMapping("/cors")
    @ResponseBody
    @CrossOrigin(origins = "http://localhost:8080", maxAge = 600) 
    public String cors( ){
        return "cors";
    }
2.3 使用CorsFilter进行(全局跨域配置)

一个个的加注解实际开发不可取,所以定义过滤器,实现统一处理,是最常用的手段。

    @Configuration
    public class GlobalCorsConfig {
        @Bean
        public CorsFilter corsFilter() {
            CorsConfiguration config = new CorsConfiguration();
            //开放哪些ip、端口、域名的访问权限,星号表示开放所有域
            config.addAllowedOrigin("*");
            //是否允许发送Cookie信息
            config.setAllowCredentials(true);
            //开放哪些Http方法,允许跨域访问
            config.addAllowedMethod("GET","POST", "PUT", "DELETE");
            //允许HTTP请求中的携带哪些Header信息
            config.addAllowedHeader("*");
            //暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息)
            config.addExposedHeader("*");
    
            //添加映射路径,“/**”表示对所有的路径实行全局跨域访问权限的设置
            UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
            configSource.registerCorsConfiguration("/**", config);
    
            return new CorsFilter(configSource);
        }
    }
2.4 重写WebMvcConfigurer的addCorsMappings方法(全局跨域配置)

这个也是SpringMvc提供的,相对过滤器性能会更高。

    @Configuration
    public class GlobalCorsConfig {
        @Bean
        public WebMvcConfigurer corsConfigurer() {
            return new WebMvcConfigurer() {
                @Override
                public void addCorsMappings(CorsRegistry registry) {
                    registry.addMapping("/**")    //添加映射路径,“/**”表示对所有的路径实行全局跨域访问权限的设置
                            .allowedOrigins("*")    //开放哪些ip、端口、域名的访问权限
                            .allowCredentials(true)  //是否允许发送Cookie信息 
                            .allowedMethods("GET","POST", "PUT", "DELETE")     //开放哪些Http方法,允许跨域访问
                            .allowedHeaders("*")     //允许HTTP请求中的携带哪些Header信息
                            .exposedHeaders("*");   //暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息)
                }
            };
        }
    }

3、在 Nginx 等反向代理解决跨域

原本浏览器是访问 localhost:8080/api请求后端服务的接口,现在让 Nginx 监听 8080 端口,把请求转发到后端服务新的端口 80801 上。Nginx 接收到后端服务的响应后,添加相关的 CORS 头部返回给浏览器,就不会报跨域的问题。
同理,转发对应的protocol(协议)、domain(域名)也是可行的。

events {}
http {
   server {
     listen          8080;
     server_name     localhost;
     location / {
       if ($request_method = 'OPTIONS') {
         add_header 'Access-Control-Allow-Origin' 'http://127.0.0.1:8080';
         add_header 'Access-Control-Allow-Methods' 'PUT,DELETE';
         add_header 'Access-Control-Allow-Headers' 'Test-CORS, Content-Type';
         add_header 'Access-Control-Max-Age' 1728000;
         add_header 'Access-Control-Allow-Credentials' 'true';
         add_header 'Content-Length' 0;
         return 204;
       }
   
       #Access-Control-Allow-Origin是必须的,其他可选
       add_header 'Access-Control-Allow-Origin' 'http://127.0.0.1:8080';  
       add_header 'Access-Control-Allow-Credentials' 'true';
   
       proxy_pass http://127.0.0.1:80801;
       proxy_set_header Host $host;
     }
   }
}

4、Websocket

webSocket本身不存在跨域问题,所以我们可以利用webSocket来进行非同源之间的通信。

5、浏览器允许跨域

我们使用命令行输入下面指令打开Chrome,此时浏览器会提醒:您使用的是不受支持的命令行标记:--disable-web-security。稳定性和安全性会有所下降

open -n "/Applications/Google Chrome.app" --args --disable-web-security  --user-data-dir=yourdir

我们同样的在简书主页请求百度,却可以正常返回了,不会报跨域错误。

浏览器运行跨域

参考链接

https://developer.aliyun.com/article/841748
https://juejin.cn/post/6844903991558537223

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353

推荐阅读更多精彩内容