IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> CORS解决跨域问题(及Nginx配置) -> 正文阅读

[系统运维]CORS解决跨域问题(及Nginx配置)

概念

跨域:
同域:域名(父域名和子域名都相同),端口,协议都相同。
跨域:非同域的请求。

  1. 跨域指的是浏览器不能执行其它网站的脚本,它是由浏览器的同源策略造成的,是浏览器对JavaScript 施加的安全限制。
  2. 浏览器在执行脚本的时候,都会检查这个脚本属于哪个页面,即检查是否同源,只有同源的脚本才会被执行;而非同源的脚本在请求数据的时候,浏览器会报一个异常,提示拒绝访问。

注意:
跨域不是请求发不出去,而是服务端正常返回结果后被浏览器拦截返回结果。(浏览器为了防止非同源的请求 拿到服务器的返回数据结果)

解决办法

跨域资源共享 CORS
因为是目前主流的跨域解决方案。所以这里多介绍点。

简介

CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。 它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。

CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。IE8+:IE8/9需要使用XDomainRequest对象来支持CORS。

整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。 因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

跨域有2种请求,浏览器对于2种请求的处理不一样

简单请求

请求方法只能是:HEAD,GET,POST

主动设置的头信息不能超过以下字段:Accept,Accept-Language,Content-Language,Last-Event-ID,Content-Type(只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain)

注意:这里的头信息是指我们主动设置的头部信息,在查看请求过程时会发现 浏览器会在头信息里设置Origin等信息,这些不算主动设置的。

简单请求:
浏览器会在 请求头信息 里增加一个Origin字段,表明本次请求的来源,若服务器返回的头部信息里需包含 Access-Control-Allow-Origin并包含Origin 则浏览器正常返回数据,否则出现跨域错误。

如果需要携带cookie,请求时需设置(比如XMLHttpRequest.withCredentials = true)。若返回头部信息有 Access-Control-Allow-Credentials:true,则浏览器会正常返回数据,否则浏览器会拦截结果报 跨域错误。

注意:服务器会正常返回数据,只是浏览器拦截了结果。

服务器在返回头信息里设置(必须):

Access-Control-Allow-Origin: Origin

Eg:Access-Control-Allow-Origin:127.0.0.1:80

如果想设置匹配所有的Origin且不带cookie的,可以设置:

Access-Control-Allow-Origin: *

如果需要带Cookie,需设置:

Access-Control-Allow-Credentials:true

如果想匹配所有的Origin且带cookie:

Access-Control-Allow-Credentials: true

Access-Control-Allow-Origin: 请求的Origin(从request获取后填入)
千万不能同时设置Credentials=true且Origin=*,浏览器会报错:

非简单请求

不能同时满足简单请求的2个条件。

常见的情况是请求方法是PUT 或者 Content-Type字段类型是application/json 或者 头信息里自定义了属性

add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers Accept,Origin,X-Requested-With,Content-Type,Last-Modified,JSESSIONID,token;
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
if ($request_method = 'OPTIONS'){
	return 204;
}

或者

add_header 'Access-Control-Allow-Origin' $http_origin;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,web-token,app-token,Authorization,Accept,Origin,Keep-Alive,User-Agent,X-Mx-ReqToken,X-Data-Type,X-Auth-Token,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
if ($request_method = 'OPTIONS') {
	add_header 'Access-Control-Max-Age' 1728000;
	add_header 'Content-Type' 'text/plain; charset=utf-8';
	add_header 'Content-Length' 0;
	return 204;
}

一般放在location块下 (nginx.cnf)。

解释:
1、Access-Control-Allow-Origin,这里使用变量 $http_origin取得当前来源域,也可以用“*”代表允许所有;

2、Access-Control-Allow-Credentials,为 true 的时候指请求时可带上Cookie,自己按情况配置吧;

3、Access-Control-Allow-Methods,OPTIONS一定要有的,另外一般也就GET和POST,如果你有其它的也可加进去;

4、Access-Control-Allow-Headers,这个要注意,里面一定要包含自定义的http头字段(就是说前端请求接口时,如果在http头里加了自定义的字段,这里配置一定要写上相应的字段),从上面可看到我写的比较长,我在网上搜索一些常用的写进去了,里面有“web-token”和“app-token”,这个是我项目里前端请求时设置的,所以我在这里要写上;

5、Access-Control-Expose-Headers,可不设置,看网上大致意思是默认只能获返回头的6个基本字段,要获取其它额外的,先在这设置才能获取它;

6、语句“ if ($request_method = ‘OPTIONS’) { ”,因为浏览器判断是否允许跨域时会先往后端发一个 options 请求,然后根据返回的结果判断是否允许跨域请求,所以这里单独判断这个请求,然后直接返回;

配置

nginx

nginx里完整的跨域配置:

     server {
         listen  80 default_server;
         server_name _;  
 
         add_header Access-Control-Allow-Credentials true;
         add_header Access-Control-Allow-Origin $http_origin;
         
              
         location /file {
            if ($request_method = 'OPTIONS') {
                add_header Access-Control-Allow-Origin $http_origin;
                add_header Access-Control-Allow-Methods $http_access_control_request_method;
                add_header Access-Control-Allow-Credentials true;
                add_header Access-Control-Allow-Headers $http_access_control_request_headers;
                add_header Access-Control-Max-Age 1728000;
                return 204;
             }         
        }
 
    }

Java里

@Configuration
public class CorsConfig {
 
    @Bean
    public CorsFilter corsFilter() {
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        final CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true); //支持cookie 跨域
        config.setAllowedOrigins(Arrays.asList("*"));
        config.setAllowedHeaders(Arrays.asList("*"));
        config.setAllowedMethods(Arrays.asList("*"));
        config.setMaxAge(300L);//设置时间有效
 
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}


参考

http://www.ruanyifeng.com/blog/2016/04/cors.html
https://www.imooc.com/article/21976

Java 测试

https://howtodoinjava.com/java/servlets/java-cors-filter-example/
https://howtodoinjava.com/spring-boot2/spring-cors-configuration/

前端测试

在浏览器上打开一个网站(非https的网站),F12后在console里输入

(function loadXMLDoc() {
	var xmlhttp;
	xmlhttp = new XMLHttpRequest();
	xmlhttp.onreadystatecatechange = function() {
                }
	xmlhttp.open("GET", "http://1.11.111.23:6088/event/list", true);
	xmlhttp.withCredentials = true;
    xmlhttp.send();
})()
  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-08-31 15:52:22  更:2021-08-31 15:53:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 11:39:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码