跨域(CrossOrigin)
citgpt 2024-10-25 11:57 19 浏览 0 评论
1. 介绍
1) 跨域问题:跨域问题是在网络中,当一个网络的运行脚本(通常时JavaScript)试图访问另一个网络的资源时,如果这两个网络的端口、协议和域名不一致时就会出现跨域问题。
通俗讲,当一个请求的URL的端口、协议和域名三者之间任意一个与当前页面的URL不同即为跨域。
换句话说,跨域问题就是浏览器的一种安全策略,限制了网页在不同源(Origin)之间进行的某些操作;如:读取网页的数据,资源等。
2) 为什么会发生跨域问题:跨域问题的发生源于浏览器的同源策略(Same-Origin Policy),这是浏览器的一种安全机制(是一种约定),旨在防止恶网站户获取用户数据。同源策略要求一个网页的JavaScript脚本只能与同一个端口、协议和域名的资源进行交互,而不能访问与其来源不同的资源。
如此设计为了保护用户的隐私和安全,防止恶意网站通过脚本等方式获取用户在其它网站的数据。如果缺少同源策略,浏览器的正常功能都会受到影响。
2. 跨域解决方案
1) JSONP(JSON with Padding):JSONP时一种古旧的跨域解决方案,利用<script>标签不受同源策略的特性,通过动态创建<script>标签来获取跨域资源。
1.客户端(前端)构造一个包含了回调函数的 URL 请求,并将这个 URL 作为 <script> 标签的 src 属性值。
2.服务器端(后端)接收到这个请求后,解析其中的回调函数名,并将相应的 JSON 数据作为参数传入该回调函数。
3.客户端定义了一个全局的 JavaScript 函数,其函数名就是前面提到的回调函数名,服务器返回的 JSON 数据作为该函数的参数。
4.当浏览器加载这个包含 JSON 数据的 JavaScript 文件时,就会立即执行这个全局函数,从而完成跨域数据的获取和处理。
JSONP的缺点:
安全性问题:不受同源策略的限制,无法保证从服务器返回的数据是否安全可信;
仅支持GET请求:限制了在处理其他类型的HTTP请求;
依赖回调函数:需要在客户端命名一个全局的JavaScript函数来处理返回的数据,意味着客户端需提前约定好回调函数的名称,容易引发命名冲突和管理困难;
无法处理错误信息:JSONP请求没有像Ajax请求那样的错误处理机制,无法捕获服务器返回的HTTP状态码和错误信息,使得调试和处理错误变得困难;
总之,并不建议使用JSONP方式解决跨域问题。
2) 添加响应头(后端)
跨域资源共享(CORS):是一种跨域解决方案,通过在服务器端添加特定的响应头来允许跨域请求。
Access-Control-Allow-Origin: 指定允许访问该资源的源,可以是单个源或者是通配符 *,表示允许所有源访问该资源。
例:在Java 控制器(Controller)方法中,使用 HttpServletResponse 对象来设置响应头信息。在 Controller 方法中设置 CORS 响应头,指定允许访问的来源(origins)。
@RestController
public class CrossOriginController {
@CrossOrigin(origins = "http://127.0.0.1:8080") // 只允许单个来源
@CrossOrigin(origins = {"http://moudu.com", "http://mouxun.com"}) // 允许多个来源
public String Test(HttpServletResponse httpServletResponse) {
return "Hello, CORS.";
}
}
注意:在Spring Framework内,@CrossOrigin注解不可以在同一个方法内多次使用。可以在同一个控制层的每个方法内使用。
常用CROS响应头:
1.Access-Control-Allow-Origin: 指定允许访问该资源的源,可以是单个源或者是通配符 *,表示允许所有源访问该资源。
2.Access-Control-Allow-Methods: 指定允许的 HTTP 方法,例如 GET、POST 等。
3.Access-Control-Allow-Headers: 指定允许的 HTTP 头字段。
4.Access-Control-Allow-Credentials: 指定是否允许发送 Cookie。
5.Access-Control-Expose-Headers: 指定哪些 HTTP 头字段可以在客户端进行访问。
6.Access-Control-Max-Age: 指定预检请求的有效期,单位为秒。
3) 配置文件(后端常用)
在Spring Boot中,可以使用配置文件设置全局的跨域策略。然后让Spring Boot应用程序在每个请求中配用这些配置。
项目需要简单的全局跨域配置,并且习惯于基于配置的开发模式,配置文件方式更适合。
优点:
配置简单,一次配置后整个应用程序都会生效;
简单的全局跨域配置,适合于小型项目或不需要复杂跨域策略的应用;
application.properties 文件中配置跨域策略:
# 允许的跨域来源
cors.allowed-origins=http://127.0.0.1:8080,http://moudu.com,http://mouxun.com
# 允许的跨域方法
cors.allowed-methods=GET,POST,PUT,DELETE
# 允许的跨域头
cors.allowed-headers=Content-Type,Authorization
# 是否允许发送 Cookie
cors.allow-credentials=true
# 预检请求的有效期,单位为秒
cors.max-age=3600
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Value("${cors.allowed-origins}")
private String allowedOrigins;
@Value("${cors.allowed-methods}")
private String allowedMethods;
@Value("${cors.allowed-headers}")
private String allowedHeaders;
@Value("${cors.allow-credentials}")
private boolean allowCredentials;
@Value("${cors.max-age}")
private long maxAge;
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins(allowedOrigins.split(","))
.allowedMethods(allowedMethods.split(","))
.allowedHeaders(allowedHeaders.split(","))
.allowCredentials(allowCredentials)
.maxAge(maxAge);
}
}
简单的Servlet过滤器,用于处理跨域资源共享(CORS)请求。config包下,可直接使用;(常用)
项目需要更灵活地控制跨域策略,甚至根据请求的具体情况动态设置跨域响应头,过滤器方式更合适。
优点:
更灵活,根据具体的请求情况动态,设置跨域响应头;
可以在过滤器中编写复杂的逻辑,对请求进行定制化处理;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class HttpFilter implements Filter {
/**
*
CROS跨域常用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
*/
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//*号表示对所有请求都允许跨域访问
HttpServletResponse res = (HttpServletResponse) response;
res.addHeader("Access-Control-Allow-Credentials", "true");
res.addHeader("Access-Control-Allow-Origin", "*");
res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
res.addHeader("Access-Control-Allow-Headers", "Content-Type,X-CAF-Authorization-Token,sessionToken,X-TOKEN");
if (((HttpServletRequest) request).getMethod().equals("OPTIONS")) {
response.getWriter().println("Success");
return;
}
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
}
若都配置后发现依然存在跨域等问题时,根据前端提示查看:res.addHeader("Access-Control-Allow-Headers", "Content-Type,X-CAF-Authorization-Token,sessionToken,X-TOKEN"); 是否未添加前端需要的其他的请求头信息。
4) WebMVC全局配置(后端解决跨域最常用)
// WebMVC全局配置
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
// 设置允许跨域的路径
registry.addMapping("/**")
// 设置允许跨域请求的域名
.allowedOriginPatterns("*")
// 是否允许cookie
.allowCredentials(true)
// 设置允许的请求方式
.allowedMethods("GET", "POST", "DELETE", "PUT", "OPTIONS")
// 设置允许的header属性
.allowedHeaders("*")
// 跨域允许时间
.maxAge(3600);
}
}
5) Nginx跨域
Nginx是一个高性能的反向代理服务器,也可用作Web服务器、负载均衡等。通过Nginx,可以实现跨域请求的解决方案。一般解决的是前端静态页面在不同服务器间的访问。
使用Nginx设置跨域请求头:
安装和配置Nginx;
编辑Nginx文件;
设置跨域设置;
location / {
# 添加以下跨域配置
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS, PUT, DELETE';
add_header Access-Control-Allow-Headers 'Origin, X-Requested-With, Content-Type, Accept, Authorization';
# 支持 OPTIONS 请求
if ($request_method = 'OPTIONS') {
add_header Content-Length 0;
add_header Content-Type text/plain;
return 204;
}
}
4. 重启 Nginx 服务: 保存并关闭配置文件后,重新加载 Nginx 配置,以使更改生效:sudo systemctl reload nginx
或
server/ {
listen 80;
server_name test01.xqiangme.to;
#允许跨域请求的域,* 代表所有
add_header 'Access-Control-Allow-Origin' *;
#允许带上cookie请求
add_header 'Access-Control-Allow-Credentials' 'true';
#允许请求的方法,比如 GET/POST/PUT/DELETE
add_header 'Access-Control-Allow-Methods' *;
#允许请求的header
add_header 'Access-Control-Allow-Headers' *;
location /index.html {
alias /home/nginx/static_html/index_test01.html
}
}
相关推荐
- js中arguments详解
-
一、简介了解arguments这个对象之前先来认识一下javascript的一些功能:其实Javascript并没有重载函数的功能,但是Arguments对象能够模拟重载。Javascrip中每个函数...
- firewall-cmd 常用命令
-
目录firewalldzone说明firewallzone内容说明firewall-cmd常用参数firewall-cmd常用命令常用命令 回到顶部firewalldzone...
- epel-release 是什么
-
EPEL-release(ExtraPackagesforEnterpriseLinux)是一个软件仓库,它为企业级Linux发行版(如CentOS、RHEL等)提供额外的软件包。以下是关于E...
- FullGC详解 什么是 JVM 的 GC
-
前言:背景:一、什么是JVM的GC?JVM(JavaVirtualMachine)。JVM是Java程序的虚拟机,是一种实现Java语言的解...
-
2024-10-26 08:50 citgpt
- 跨域(CrossOrigin)
-
1.介绍 1)跨域问题:跨域问题是在网络中,当一个网络的运行脚本(通常时JavaScript)试图访问另一个网络的资源时,如果这两个网络的端口、协议和域名...
-
2024-10-25 11:57 citgpt
- 微服务架构和分布式架构的区别
-
1、含义不同微服务架构:微服务架构风格是一种将一个单一应用程序开发为一组小型服务的方法,每个服务运行在自己的进程中,服务间通信采用轻量级通信机制(通常用HTTP资源API)。这些服务围绕业务能力构建并...
- 深入理解与应用CSS clip-path 属性
-
clip-pathclip-path是什么clip-path 是一个CSS属性,允许开发者创建一个剪切区域,从而决定元素的哪些部分可见,哪些部分会被隐...
-
2024-10-25 11:51 citgpt
- Request.ServerVariables 大全
-
Request.ServerVariables("Url")返回服务器地址Request.ServerVariables("Path_Info")客户端提供的路...
- python操作Kafka
-
目录一、python操作kafka1.python使用kafka生产者2.python使用kafka消费者3.使用docker中的kafka二、python操作kafka细...
- Runtime.getRuntime().exec详解
-
Runtime.getRuntime().exec详解概述Runtime.getRuntime().exec用于调用外部可执行程序或系统命令,并重定向外部程序的标准输入、标准输出和标准错误到缓冲池。...
- promise.all详解 promise.all是干什么的
-
promise.all详解promise.all中所有的请求成功了,走.then(),在.then()中能得到一个数组,数组中是每个请求resolve抛出的结果...
-
2024-10-24 16:21 citgpt
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracleclient (56)
- springbatch (59)
- oracle恢复数据 (56)
- 简单工厂模式 (68)
- 函数指针 (72)
- fill_parent (135)
- java配置环境变量 (140)
- linux文件系统 (56)
- 计算机操作系统教程 (60)
- 静态ip (63)
- notifyicon (55)
- 线程同步 (58)
- xcode 4 5 (60)
- 调试器 (60)
- c0000005 (63)
- html代码大全 (61)
- header utf 8 (61)
- 多线程多进程 (65)
- require_once (60)
- 百度网盘下载速度慢破解方法 (72)
- 谷歌浏览器免费入口 (72)
- npm list (64)
- 网站打开速度检测 (59)
- 网站建设流程图 (58)
- this关键字 (67)