跨域-告别CORS烦恼
跨域-告别CORS烦恼
文章目录
- 跨域-告别CORS烦恼
- @[toc]
- 1-参考网址
- 2-思路整理
- 1-核心问题
- 2-个人思考
- 3-脑洞打开
- 4-个人思考-修正版
- 1-个人思考
- 2-脑洞打开
- 3-知识整理
- 1-什么是跨域
- 一、同源策略简介
- 什么是源
- 什么是同源
- 是否是同源的判断
- 哪些操作不受同源策略限制
- 跨域
- 如何跨域
- 二、CORS 简介
- 1、简单请求
- 2、非简单请求
- 三、Spring Boot 配置 CORS
- 1、使用`@CrossOrigin` 注解实现
- 2、原理剖析
- 2-Java如何配置CORS
- 1. 使用`@CrossOrigin`注解
- 2. 全局配置CORS
- 3. 使用Filter实现CORS
- 4. 使用拦截器(Interceptor)
- 5.响应体(Response Body)来设置CORS
- 6.通过**自定义`ResponseBodyAdvice`**
文章目录
- 跨域-告别CORS烦恼
- @[toc]
- 1-参考网址
- 2-思路整理
- 1-核心问题
- 2-个人思考
- 3-脑洞打开
- 4-个人思考-修正版
- 1-个人思考
- 2-脑洞打开
- 3-知识整理
- 1-什么是跨域
- 一、同源策略简介
- 什么是源
- 什么是同源
- 是否是同源的判断
- 哪些操作不受同源策略限制
- 跨域
- 如何跨域
- 二、CORS 简介
- 1、简单请求
- 2、非简单请求
- 三、Spring Boot 配置 CORS
- 1、使用`@CrossOrigin` 注解实现
- 2、原理剖析
- 2-Java如何配置CORS
- 1. 使用`@CrossOrigin`注解
- 2. 全局配置CORS
- 3. 使用Filter实现CORS
- 4. 使用拦截器(Interceptor)
- 5.响应体(Response Body)来设置CORS
- 6.通过**自定义`ResponseBodyAdvice`**
1-参考网址
- Cors解决跨域请求问题
- SpringBoot3跨域方案详解
2-思路整理
1-核心问题
- 1)什么是跨域-为什么要搞一个跨域
- 2)简单请求/非简单请求
- 3)理论上如何解决跨域问题
- 4)Java如何解决跨域问题
2-个人思考
- 1)为什么有CORS跨域->最简单的解释:前端和后端最好是部署在同一个服务器上,前后端之间使用内网IP进行访问,避免后端的API接口被其他网站访问(同源策略)
- 2)但我们为什么没有这样做->多种原因:①前后端分离架构 ②后端多实例容灾 ③等等其他元素 ->前后端分析引发现象:前端必须使用IP或者域名进行访问后端
- 3)又引发运维上的问题->后端的IP或者域名会变,但是前端又不能总是更换后端IP或者域名->一劳永逸的解决方案:后端直接全部放开API的接口调用
- 4)域名不校验岂不是要翻天->解决方案:①前后端鉴权使用API-KEY或者其他鉴权措施 ②公有云的防御服务
- 5)那为什么我本地开发可以访问很多网站的API接口->因为开发人员没有注意这些情况,或者网站本身就是对外提供API访问的网站
3-脑洞打开
- 1)开发侧-如果我做静态个人网站,我如何进行跨域限制(防止网站被恶意攻击)
- 2)开发侧-如果我做SDK服务型网站,我如何进行跨域限制(防止网站被恶意攻击)
- 3)爬虫侧-如和避免网站的API接口被爬取,如何定义自己的robots.txt
4-个人思考-修正版
你的理解总体上是正确的,但有一些地方可以进一步完善和修正:
1-个人思考
-
为什么有CORS跨域
- 最简单的解释
:前端和后端最好是部署在同一个服务器上,前后端之间使用内网IP进行访问,避免后端的API接口被其他网站访问(同源策略)。这个说法基本正确,但同源策略不仅是为了避免后端API被其他网站访问,更是为了保护用户的数据安全,防止恶意网站通过用户浏览器窃取敏感信息。 - 同源策略:浏览器的同源策略限制了一个文档或脚本从一个源访问另一个源的资源,除非满足同源条件(协议、域名、端口都相同)。这是浏览器提供的一种安全机制,用于防止恶意网站读取其他网站的敏感数据。
- 最简单的解释
-
但我们为什么没有这样做
- 多种原因:
- 前后端分离架构:现代Web开发中,前后端分离架构很常见,前端负责展示和交互,后端负责数据处理和业务逻辑,两者通常部署在不同的服务器上。
- 后端多实例容灾:为了提高系统的可用性和可靠性,后端可能有多个实例部署在不同的服务器或数据中心,前端需要访问不同的后端实例。
- 其他元素:比如微服务架构,不同的服务可能部署在不同的服务器上,前端需要调用多个服务的API。
- 前后端分析引发现象:前端必须使用IP或者域名进行访问后端。这个说法不完全准确,前端可以通过多种方式访问后端,比如通过域名、IP、负载均衡器等。
- 多种原因:
-
又引发运维上的问题
- 后端的IP或者域名会变:确实,在实际运维中,后端的IP或者域名可能会因为各种原因发生变化,比如服务器迁移、负载均衡器调整等。
- 但是前端又不能总是更换后端IP或者域名:这个说法正确,频繁更换前端配置不现实,也不方便。
- 一劳永逸的解决方案:后端直接全部放开API的接口调用。这个解决方案不安全,不能简单地全部放开,否则会导致安全风险,比如跨站请求伪造(CSRF)攻击、恶意爬虫等。
-
域名不校验岂不是要翻天
- 解决方案:
- 前后端鉴权使用API-KEY或者其他鉴措施权:正确,通过API-KEY、OAuth、JWT等方式进行鉴权,可以确保只有授权的请求才能访问后端API。
- 公有云的防御服务:正确,公有云平台提供了一系列的安全服务,比如防火墙、DDoS防护、WAF(Web应用防火墙)等,可以有效防止恶意攻击。
- 解决方案:
-
那为什么我本地开发可以访问很多网站的API接口
- 因为开发人员没有注意这些情况:这个说法不完全准确,很多网站的API是对外提供服务的,允许其他网站或开发者调用但,通常会有一些限制,比如需要注册、申请API密钥等。
- 或者网站本身就是对外提供API访问的网站:正确,比如一些开放平台,如微博、微信等,它们的API就是对外提供服务的,供开发者集成到自己的应用中。
2-脑洞打开
-
开发侧-如果我做静态个人网站,我如何进行跨域限制(防止网站被恶意攻击)
- 跨域限制:可以通过设置CORS(跨域资源共享)策略来限制哪些网站可以访问你的API。例如,在服务器配置中,只允许特定的域名访问你的API。
- 防止恶意攻击:除了CORS,还可以采取其他安全措施,比如使用防火墙、限制请求频率、使用验证码等。
-
开发侧-如果我做SDK服务型网站,我如何进行跨域限制(防止网站被恶意攻击)
- 跨域限制:同样可以通过CORS策略来限制访问,还可以要求调用方提供API密钥或其他身份验证信息。
- 防止恶意攻击:可以对请求进行签名验证,确保请求的合法性;还可以对请求进行限流,防止恶意爬虫或攻击导致服务器过载。
-
爬虫侧-如和避免网站的API接口被爬取,如何定义自己的robots.txt
- 避免被爬取:可以通过技术手段,比如限制请求频率、验证请求来源、使用验证码等,来防止恶意爬虫。
- 定义robots.txt:
robots.txt
文件是网站根目录下的一个文本文件,用于告诉搜索引擎和其他爬虫哪些页面可以爬取,哪些不可以爬取。例如:
但要注意,User-agent: * Disallow: /api/ # 禁止爬虫访问API接口 Allow: /public/ # 允许爬虫访问公开的资源
robots.txt
只是一种君子协议,恶意爬虫可能会忽略它,所以还需要其他安全措施来保护API接口。
3-知识整理
1-什么是跨域
一、同源策略简介
同源策略(same origin policy)是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。同源策略是浏览器安全的基石。
什么是源
源(origin)就是协议、域名和端口号。例如:http://www.baidu.com:80这个URL。
什么是同源
若地址里面的协议、域名和端口号均相同则属于同源。
是否是同源的判断
例如判断下面的URL
是否与 http://www.a.com/test/index.html 同源
- http://www.a.com/dir/page.html 同源
- http://www.child.a.com/test/index.html 不同源,域名不相同
- https://www.a.com/test/index.html 不同源,协议不相同
- http://www.a.com:8080/test/index.html 不同源,端口号不相同
哪些操作不受同源策略限制
- 页面中的链接,重定向以及表单提交是不会受到同源策略限制的;
- 跨域资源的引入是可以的。但是
JS
不能读写加载的内容。如嵌入到页面中的<script src="..."></script>
,<img>
,<link>
,<iframe>
等。
跨域
受前面所讲的浏览器同源策略的影响,不是同源的脚本不能操作其他源下面的对象。想要操作另一个源下的对象就需要跨域。 在同源策略的限制下,非同源的网站之间不能发送 AJAX
请求。
如何跨域
-
降域
可以通过设置
document.domain='a.com'
,浏览器就会认为它们都是同一个源。想要实现以上任意两个页面之间的通信,两个页面必须都设置document.domain='a.com'
。 -
JSONP
跨域 -
CORS
跨域
二、CORS 简介
为了解决浏览器同源问题,W3C
提出了跨源资源共享,即 CORS
(Cross-Origin Resource Sharing)。
CORS
做到了如下两点:
- 不破坏即有规则
- 服务器实现了
CORS
接口,就可以跨源通信
基于这两点,CORS
将请求分为两类:简单请求和非简单请求。
1、简单请求
在CORS
出现前,发送HTTP
请求时在头信息中不能包含任何自定义字段,且 HTTP
头信息不超过以下几个字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type
只限于 [application/x-www-form-urlencoded
、multipart/form-data
、text/plain
] 类型
一个简单的请求例子:
GET /test HTTP/1.1Accept: */*Accept-Encoding: gzip, deflate, sdch, brOrigin: http://www.examples.comHost: www.examples.com
对于简单请求,CORS
的策略是请求时在请求头中增加一个Origin
字段,服务器收到请求后,根据该字段判断是否允许该请求访问。
- 如果允许,则在 HTTP 头信息中添加
Access-Control-Allow-Origin
字段,并返回正确的结果 ; - 如果不允许,则不在 HTTP 头信息中添加
Access-Control-Allow-Origin
字段 。
除了上面提到的 Access-Control-Allow-Origin
,还有几个字段用于描述 CORS
返回结果 :
Access-Control-Allow-Credentials
: 可选,用户是否可以发送、处理cookie
;Access-Control-Expose-Headers
:可选,可以让用户拿到的字段。有几个字段无论设置与否都可以拿到的,包括:Cache-Control
、Content-Language
、Content-Type
、Expires
、Last-Modified
、Pragma
。
2、非简单请求
对于非简单请求的跨源请求,浏览器会在真实请求发出前,增加一次OPTION
请求,称为预检请求(preflight request
)。预检请求将真实请求的信息,包括请求方法、自定义头字段、源信息添加到 HTTP
头信息字段中,询问服务器是否允许这样的操作。
例如一个DELETE
请求:
OPTIONS /test HTTP/1.1Origin: http://www.examples.comAccess-Control-Request-Method: DELETEAccess-Control-Request-Headers: X-Custom-HeaderHost: www.examples.com
与 CORS
相关的字段有:
- 请求使用的
HTTP
方法Access-Control-Request-Method
; - 请求中包含的自定义头字段
Access-Control-Request-Headers
。
服务器收到请求时,需要分别对 Origin
、Access-Control-Request-Method
、Access-Control-Request-Headers
进行验证,验证通过后,会在返回 HTTP
头信息中添加 :
Access-Control-Allow-Origin: http://www.examples.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: X-Custom-Header
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 1728000
他们的含义分别是:
Access-Control-Allow-Methods
: 真实请求允许的方法Access-Control-Allow-Headers
: 服务器允许使用的字段Access-Control-Allow-Credentials
: 是否允许用户发送、处理 cookieAccess-Control-Max-Age
: 预检请求的有效期,单位为秒。有效期内,不会重复发送预检请求
当预检请求通过后,浏览器会发送真实请求到服务器。这就实现了跨源请求。
三、Spring Boot 配置 CORS
1、使用@CrossOrigin
注解实现
如果想要对某一接口配置 CORS
,可以在方法上添加 @CrossOrigin
注解 :
@CrossOrigin(origins = {"http://localhost:9000", "null"})
@RequestMapping(value = "/test", method = RequestMethod.GET)
public String greetings(){return"{\"project\":\"just a test\"}";
}
如果想对一系列接口添加 CORS 配置,可以在类上添加注解,对该类声明所有接口都有效:
@CrossOrigin(origins = {"http://localhost:9000", "null"})
@RestController
@SpringBootApplication
public class SpringBootCorsTestApplication {
}
如果想添加全局配置,则需要添加一个配置类 :
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowedOrigins("*").allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE").maxAge(3600).allowCredentials(true);}
}
另外,还可以通过添加 Filter 的方式,配置 CORS 规则,并手动指定对哪些接口有效。
@Bean
public FilterRegistrationBean corsFilter(){UrlBasedCorsConfigurationSource source=new UrlBasedCorsConfigurationSource();CorsConfiguration config=new CorsConfiguration();config.setAllowCredentials(true);config.addAllowedOrigin("http://localhost:9000");config.addAllowedOrigin("null");config.addAllowedHeader("*");config.addAllowedMethod("*");source.registerCorsConfiguration("/**",config); // CORS 配置对所有接口都有效FilterRegistrationBean bean=new FilterRegistrationBean(new CorsFilter(source));bean.setOrder(0);return bean;}
2、原理剖析
无论是通过哪种方式配置 CORS
,其实都是在构造 CorsConfiguration
。一个 CORS
配置用一个 CorsConfiguration
类来表示,它的定义如下:
public class CorsConfiguration {private List<String> allowedOrigins;private List<String> allowedMethods;private List<String> allowedHeaders;private List<String> exposedHeaders;private Boolean allowCredentials;private Long maxAge;
}
Spring
中对 CORS
规则的校验,都是通过委托给 DefaultCorsProcessor
实现的。
DefaultCorsProcessor
处理过程如下:
- 判断依据是
Header
中是否包含Origin
。如果包含则说明为CORS
请求,转到 2;否则,说明不是CORS
请求,不作任何处理。 - 判断
response
的Header
是否已经包含Access-Control-Allow-Origin
,如果包含,证明已经被处理过了, 转到 3,否则不再处理。 - 判断是否同源,如果是则转交给负责该请求的类处理。
- 是否配置了
CORS
规则,如果没有配置,且是预检请求,则拒绝该请求,如果没有配置,且不是预检请求,则交给负责该请求的类处理。如果配置了,则对该请求进行校验。
校验就是根据 CorsConfiguration
这个类的配置进行判断:
- 判断
origin
是否合法 - 判断
method
是否合法 - 判断
header
是否合法 - 如果全部合法,则在
response header
中添加响应的字段,并交给负责该请求的类处理,如果不合法,则拒绝该请求。
2-Java如何配置CORS
在Spring Boot
3中,解决跨域请求(CORS,Cross-Origin
Resource Sharing)的问题主要有以下几种方式:
1. 使用@CrossOrigin
注解
你可以直接在Controller类或者具体的请求处理方法上使用@CrossOrigin
注解来允许跨域请求。
@RestController
@RequestMapping("/user")
@CrossOrigin(origins = "*")
public class UserController {}
在这个例子中,@CrossOrigin
注解被添加到了控制器类上,表示这个控制器下的所有方法都允许来自http://example.com
的GET和POST请求。你也可以将注解添加到特定的方法上,以对该方法应用CORS配置。
2. 全局配置CORS
如果你希望全局配置CORS,而不是在每个Controller或方法上单独配置,你可以创建一个配置类来实现WebMvcConfigurer
接口,并重写addCorsMappings
方法。
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class CorsConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowedOrigins("*").allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE").allowedHeaders("*").allowCredentials(true).maxAge(168000);}
}
在这个配置中,addMapping("/**")
表示对所有的路径都应用CORS配置。allowedOrigins("*")
表示允许所有来源的访问,这在生产环境中可能不是最佳实践,通常你会指定具体的域名。allowedMethods
定义了允许的HTTP方法,allowedHeaders
定义了允许的HTTP头部,allowCredentials(true)
表示是否允许携带凭证(cookies, HTTP认证及客户端SSL证明等),maxAge
则用于设置预检请求的有效期。
3. 使用Filter实现CORS
你也可以通过实现Filter
接口来自定义CORS处理逻辑。
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;public class SimpleCorsFilter implements Filter {@Overridepublic void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)throws IOException, ServletException {HttpServletResponse response = (HttpServletResponse) res;response.setHeader("Access-Control-Allow-Origin", "http://example.com");response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");response.setHeader("Access-Control-Max-Age", "3600");response.setHeader("Access-Control-Allow-Headers", "x-requested-with");chain.doFilter(req, res);}@Overridepublic void init(FilterConfig filterConfig) {}@Overridepublic void destroy() {}}
然后需要在配置类中注册这个Filter。
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class FilterConfig {@Beanpublic FilterRegistrationBean<SimpleCorsFilter> corsFilter() {FilterRegistrationBean<SimpleCorsFilter> registrationBean = new FilterRegistrationBean<>();registrationBean.setFilter(new SimpleCorsFilter());registrationBean.addUrlPatterns("/*");return registrationBean;}}
4. 使用拦截器(Interceptor)
如果需要更复杂的CORS逻辑,你可以创建一个拦截器来处理CORS请求。拦截器允许你在请求处理之前或之后添加逻辑。
import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class CorsInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {response.setHeader("Access-Control-Allow-Origin", "http://example.com");response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");response.setHeader("Access-Control-Allow-Headers", "*");return true;}
}
然后,你需要在配置类中注册这个拦截器:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate CorsInterceptor corsInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(corsInterceptor).addPathPatterns("/**");}}
- 当设置
allowedHeaders("*")
时,实际上浏览器会发送实际请求头而不是*
。出于安全考虑,最好明确指定允许的头部。 - 在生产环境中,确保不要过于宽松地配置CORS,只允许必要的源和方法。
- 如果你的应用部署在代理服务器后面(如Nginx或Apache),可能还需要在代理服务器上配置CORS。
5.响应体(Response Body)来设置CORS
虽然这种方式不如前面提到的几种方法直接和常用,但在某些特殊场景下,你可能需要手动控制响应头来实现跨域。
具体实现时,你可以在Controller的方法中,通过HttpServletResponse对象来设置Access-Control-Allow-Origin等CORS相关的HTTP头。
import javax.servlet.http.HttpServletResponse;import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class MyController {@GetMapping("/data")public String getData(HttpServletResponse response) {response.setHeader("Access-Control-Allow-Origin", "http://example.com");response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");response.setHeader("Access-Control-Allow-Headers", "*");response.setHeader("Access-Control-Max-Age", "3600");return "Data";}}
需要注意的是,手动设置响应头的方式相对繁琐,且容易遗漏某些必要的头信息,导致CORS配置不完整。因此,在实际开发中,推荐使用前面提到的方法,它们更为直接且易于管理。
此外,如果你正在使用Spring Security,还需要确保Spring Security的配置不会阻止跨域请求的处理。在某些情况下,你可能需要在Spring Security的配置中允许特定的CORS请求。
6.通过自定义ResponseBodyAdvice
ResponseBodyAdvice
是Spring MVC提供的一个接口,允许你在Controller方法返回响应体之前对其进行修改。虽然它本身不是专为CORS设计的,但你可以利用它在返回响应之前添加CORS相关的HTTP头。
下面是一个简单的示例,展示了如何通过实现ResponseBodyAdvice
接口来添加CORS头:
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;import java.lang.reflect.Type;public class CorsResponseBodyAdvice implements ResponseBodyAdvice<Object> {@Overridepublic boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {return true;}@Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,Class<? extends HttpMessageConverter<?>> selectedConverterType,ServerHttpRequest request, ServerHttpResponse response) {response.getHeaders().set("Access-Control-Allow-Origin", "http://example.com");response.getHeaders().set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");response.getHeaders().set("Access-Control-Allow-Headers", "*");return body;}
}
然后,你需要在Spring Boot的配置中注册这个ResponseBodyAdvice
:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void configureMessageConverters(List<HttpMessageConverter<?>> converters) {converters.forEach(converter -> {if (converter instanceof MappingJackson2HttpMessageConverter) {((MappingJackson2HttpMessageConverter) converter).setResponseBodyAdvice(new CorsResponseBodyAdvice());}});}}
这种方法的优点在于它可以全局地应用于所有Controller的响应,而无需在每个Controller或方法上单独设置。然而,它同样也有一些局限性,比如你可能需要手动处理一些CORS的细节,并且这种方式不如使用Spring提供的CORS支持那么直接和灵活。
在选择解决方案时,应该根据项目的具体需求和团队的偏好来权衡各种方法的优缺点。如果项目中有大量的Controller需要处理跨域请求,并且希望有一个统一且全局的解决方案,那么使用WebMvcConfigurer
或CorsFilter
可能是更好的选择。如果只需要在特定的Controller或方法上处理跨域请求,那么使用@CrossOrigin
注解可能更为简单直接。
相关文章:
跨域-告别CORS烦恼
跨域-告别CORS烦恼 文章目录 跨域-告别CORS烦恼[toc]1-参考网址2-思路整理1-核心问题2-个人思考3-脑洞打开4-个人思考-修正版1-个人思考2-脑洞打开 3-知识整理1-什么是跨域一、同源策略简介什么是源什么是同源是否是同源的判断哪些操作不受同源策略限制跨域如何跨域 二、CORS 简…...
浅论数据库聚合:合理使用LambdaQueryWrapper和XML
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、数据库聚合替代内存计算(关键优化)二、批量处理优化四、区域特殊处理解耦五、防御性编程增强 前言 技术认知点:使用 XM…...
css实现元素垂直居中显示的7种方式
文章目录 * [【一】知道居中元素的宽高](https://blog.csdn.net/weixin_41305441/article/details/89886846#_1) [absolute 负margin](https://blog.csdn.net/weixin_41305441/article/details/89886846#absolute__margin_2) [absolute margin auto](https://blog.csdn.net…...
Nerf流程
一.数据处理: 在输入数据时,并没有给出相机的内参与外参,需要在数据处理得出相机的内外惨数,作者使用COLMAP得到相机参数后,转成NeRF可以读取的格式即可以用于模型训练。 旋转矩阵的第一列到第三列分别表示了相机坐标系…...
Spring Cloud Alibaba学习 5- Seata入门使用
Spring Cloud Alibaba学习 5- Seata入门使用 Seata是Spring Cloud Alibaba中用于分布式事务管理的解决方案 一. Seata的基本概念 1. Seata的三大角色 1> TC (Transaction Coordinator) - 事务协调者 维护全局和分支事务的状态,驱动全局事务提交或回滚。TC作…...
Select 下拉菜单选项分组
使用<select>元素创建下拉菜单,并使用 <optgroup> 元素对选项进行分组。<optgroup> 元素允许你将相关的 <option> 元素分组在一起,并为每个分组添加一个标签。 <form action"#" method"post"><la…...
【无人机与无人车协同避障】
无人机与无人车协同避障的关键在于点云数据的采集、传输、解析及实时应用,以下是技术实现的分步解析: 1. 点云数据采集(无人机端) 传感器选择: LiDAR:通过激光雷达获取高精度3D点云(精度达厘米…...
AI视频领域的DeepSeek—阿里万相2.1图生视频
让我们一同深入探索万相 2.1 ,本文不仅介绍其文生图和文生视频的使用秘籍,还将手把手教你如何利用它实现图生视频。 如下为生成的视频效果(我录制的GIF动图) 如下为输入的图片 目录 1.阿里巴巴全面开源旗下视频生成模型万相2.1模…...
飞机大战lua迷你世界脚本
-- 迷你世界飞机大战 v1.2 -- 星空露珠工作室制作 -- 最后更新:2024年1月 ----------------------------- -- 迷你世界API适配配置 ----------------------------- local UI { BASE_ID 7477478487091949474-22856, -- UI界面ID ELEMENTS { BG 1, -- 背景 BTN_LE…...
Android15请求动态申请存储权限完整示例
效果: 1.修改AndroidManifest.xml增加如下内容: <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-perm...
Java 导出大数据到 Excel 表格
背景 之前的项目一直是用XSSFWorkbook来做 Excel 导出,在遇到大数据导出时,经常会遇到 OOM。在 Apache Poi 3.8 之后的版本提供的 SXSSFWorkbook 可以优雅的解决这个问题。 原理 SXSSFWorkbook 被称为流式 API,主要是因为它采用了流式写入…...
GCC RISCV 后端 -- GCC Passes 注释
在前面文章提到,当GCC 前端完成对C源代码解析完成后,就会使用 处理过程(Passes)机制,通过一系列的处理过程,将 GENERIC IR 表示的C程序 转步转换成 目标机器的汇编语言。过程描述如下图所示: 此…...
稚晖君级硬核:智元公司开源机器人通信框架AimRT入驻GitCode平台
在科技的浪潮中,机器人技术正以前所未有的速度发展。它们不再只是科幻小说中的概念,而是逐渐融入到我们的日常生活中,从工厂的自动化生产线到家庭的智能助手,机器人的身影无处不在。然而,随着机器人应用的日益复杂&…...
STM32L051系列单片机低功耗应用
STM32L051单片机支持多种低功耗模式,包括 Sleep(睡眠)、Stop(停止) 和 Standby(待机) 模式。不同模式的功耗和唤醒方式不同。 一、低功耗相关介绍 1.1 低功耗模式概览 模式功耗唤醒源时钟状态…...
【代码分享】基于IRM和RRT*的无人机路径规划方法详解与Matlab实现
基于IRM和RRT*的无人机路径规划方法详解与Matlab实现 1. IRM与RRT*的概述及优势 IRM(Influence Region Map)通过建模障碍物的影响区域,量化环境中的安全风险,为RRT算法提供启发式引导。RRT(Rapidly-exploring Random…...
【JAVA架构师成长之路】【JVM实战】第1集:生产环境CPU飙高排查实战
课程标题:生产环境CPU飙高排查实战——从现象到根因的15分钟攻防战 目标:掌握CPU飙高问题的系统性排查方法,熟练使用工具定位代码或资源瓶颈 0-1分钟:问题引入与核心影响 线上服务器CPU突然飙升至90%以上,导致服务响应延迟激增,用户投诉激增。CPU飙高可能由死循环、线程…...
android edittext 防止输入多个小数点或负号
有些英文系统的输入法,或者定制输入法。使用xml限制不了输入多个小数点和多个负号。所以代码来控制。 一、通过XML设置限制 <EditTextandroid:id="@+id/editTextNumber"android:layout_width="wrap_content"android:layout_height="wrap_conten…...
Spring MVC 页面重定向返回后通过nginx代理 丢失端口号问题处理
Spring MVC页面重定向通过Nginx代理后出现端口丢失问题,通常由以下原因及解决方案构成: ## 一、Nginx配置问题(核心原因) 1. Host头传递不完整 Nginx默认未将原始请求的端口信息传递给后端,导致应用生成重定向…...
DeepSeek V3 源码:从入门到放弃!
从入门到放弃 花了几天时间,看懂了DeepSeek V3 源码的逻辑。源码的逻辑是不难的,但为什么模型结构需要这样设计,为什么参数需要这样设置呢?知其然,但不知其所以然。除了模型结构以外,模型的训练数据、训练…...
基于国产芯片的AI引擎技术,打造更安全的算力生态 | 京东零售技术实践
近年来,随着国产AI芯片的日益崛起,基于国产AI芯片的模型适配、性能优化以及应用落地是国产AI应用的一道重要关卡。如何在复杂的京东零售业务场景下更好地使用国产AI芯片,并保障算力安全,是目前亟需解决的问题。对此,京…...
LINUX网络基础 [一] - 初识网络,理解网络协议
目录 前言 一. 计算机网络背景 1.1 发展历程 1.1.1 独立模式 1.1.2 网络互联 1.1.3 局域网LAN 1.1.4 广域网WAN 1.2 总结 二. "协议" 2.1 什么是协议 2.2 网络协议的理解 2.3 网络协议的分层结构 三. OSI七层模型(理论标准) …...
Linux 开发工具
linux中,常见的软件安装方式---下载 yum/apt.rpm安装包安装源码安装 yum 查看软件包 通过yumlist命令可以罗列出当前⼀共有哪些软件包.由于包的数⽬可能⾮常之多,这⾥我们需要使⽤ grep 命令只筛选出我们关注的包.例如: # Centos $ yum list | grep lrzsz lr…...
SpringBoot 全局异常处理
文章目录 异常处理全局异常处理(推荐)局部异常处理高级技巧设置返回状态码处理404异常异常处理 全局异常处理(推荐) 创建一个全局异常处理类,使用 @RestControllerAdvice 注解标记。 在方法上使用 @ExceptionHandler 声明当前方法可处理的异常类型。当系统发生异常时,…...
EA - 开源工程的编译
文章目录 EA - 开源工程的编译概述笔记环境备注x86版本EABase_x86EAAssert_x86EAThread_x86修改 eathread_atomic_standalone_msvc.h原始修改后 EAStdC_x86EASTL_x86EAMain_x86EATest_x86备注备注END EA - 开源工程的编译 概述 EA开源了‘命令与征服’的游戏源码 尝试编译. 首…...
springboot3 WebClient
1 介绍 在 Spring 5 之前,如果我们想要调用其他系统提供的 HTTP 服务,通常可以使用 Spring 提供的 RestTemplate 来访问,不过由于 RestTemplate 是 Spring 3 中引入的同步阻塞式 HTTP 客户端,因此存在一定性能瓶颈。根据 Spring 官…...
【Python项目】基于深度学习的车辆特征分析系统
【Python项目】基于深度学习的车辆特征分析系统 技术简介:采用Python技术、MySQL数据库、卷积神经网络(CNN)等实现。 系统简介:该系统基于深度学习技术,特别是卷积神经网络(CNN),用…...
爬虫不“刑”教程
在大数据时代,信息的获取至关重要,而网络爬虫正是帮助我们从互联网上获取海量数据的重要工具。无论是数据分析、人工智能训练数据,还是商业情报收集,爬虫技术都能发挥重要作用。本篇文章将全面解析 Python 爬虫的各个方面…...
深入解析 supervision 库:功能、用法与应用案例
1. 引言 在计算机视觉任务中,数据的后处理和可视化是至关重要的环节,尤其是在目标检测、分割、跟踪等任务中。supervision 是一个专门为这些任务提供高效数据处理和可视化支持的 Python 库。本文将深入介绍 supervision 的功能、使用方法,并…...
【橘子golang】从golang来谈闭包
一、简介 闭包(Closure)是一种编程概念,它允许函数捕获并记住其创建时的上下文环境(包括变量)。闭包通常用于函数式编程语言,但在许多现代编程语言中也有支持,包括 Go ,Js等支持函数…...
盛铂科技PDROUxxxx系列锁相介质振荡器(点频源):高精度信号源
——超低相位噪声、宽频覆盖、灵活集成,赋能下一代射频系统 核心价值:以突破性技术解决行业痛点 在雷达、卫星通信、高速数据采集等高端射频系统中,信号源的相位噪声、频率稳定度及集成灵活性直接决定系统性能上限。盛铂科技PDROUxxxx系列锁…...
Linux | Vim 鼠标不能右键粘贴、跨系统复制粘贴
注:本文为 “ Vim 中鼠标右键粘贴、跨系统复制粘贴问题解决方案” 相关文章合辑。 未整理去重。 Linux 入门:vim 鼠标不能右键粘贴、跨系统复制粘贴 foryouslgme 发布时间 2016 - 09 - 28 10:24:16 Vim 基础 命令模式(command - mode&…...
仿12306项目(4)
基本预定车票功能的开发 对于乘客购票来说,需要有每一个车次的余票信息,展示给乘客,供乘客选择,因此首个功能是余票的初始化,之后是余票查询,这两个都是控台端。对于会员端的购票,需要有余票查询…...
调研:如何实现智能分析助手(Agent)(AutoCoder、FastGPT、AutoGen、DataCopilot)
文章目录 调研:如何实现智能分析助手(Agent)(AutoCoder、FastGPT、AutoGen、DataCopilot)一、交互流程二、数据流程三、架构分类四、开源产品4.1 AutoCoder(知识库变体)4.2 FastGPT(…...
爬虫逆向:脱壳工具Youpk的使用详解
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 1. Youpk 简介1.1 Youpk介绍1.2 Youpk支持场景1.3 Youpk基本流程1.4 使用 Youpk 脱壳步骤1.5 常用的脱壳工具对比2. Youpk 的安装与使用2.1 安装 Youpk2.2 使用 Youpk 脱壳3. 脱壳后的 Dex 文件分析3.1 使用 JADX 反编译…...
Java 大视界 -- Java 大数据在智能政务公共服务资源优化配置中的应用(118)
💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…...
Java停车平台高并发抢锁技术方案设计 - 慧停宝开源停车管理平台
Java停车平台高并发抢锁技术方案设计 一、业务场景特征 瞬时流量峰值 早晚高峰时段(07:30-09:00, 17:30-19:00)请求量激增10倍热门商圈停车场每秒并发请求可达5000 QPS 资源竞争特性 单个车位被多人同时抢占(超卖风险)用户操作链…...
【论文笔记】Attentive Eraser
标题:Attentive Eraser: Unleashing Diffusion Model’s Object Removal Potential via Self-Attention Redirection Guidance Source:https://arxiv.org/pdf/2412.12974 收录:AAAI 25 作者单位:浙工商,字节&#…...
Android Flow操作符分类
Flow操作符分类...
Cursor + IDEA 双开极速交互
相信很多开发者朋友应该和我一样吧,都是Cursor和IDEA双开的开发模式:在Cursor中快速编写和生成代码,然后在IDEA中进行调试和优化 在这个双开模式的开发过程中,我就遇到一个说大不大说小不小的问题: 得在两个编辑器之间来回切换查…...
图像识别-手写数字识别项目
训练模型: 实现神经网络实例 准备数据 导入torchvision.transforms模块,它提供了许多常用的数据预处理操作,如裁剪、旋转、归一化等。 从torch.utils.data模块导入DataLoader类,用于加载数据集并提供批量处理功能。 导入tensorboa…...
推荐几款优秀的PDF转电子画册的软件
当然可以!以下是几款优秀的PDF转电子画册的软件推荐,内容简洁易懂,这些软件都具有易用性和互动性,适合不同需求的用户使用。 ❶ FLBOOK|在线创作平台 支持PDF直接导入生成仿真翻页电子书。提供15主题模板与字体库&a…...
bert模型笔记
1.各预训练模型说明 BERT模型在英文数据集上提供了两种大小的模型,Base和Large。Uncased是意味着输入的词都会转变成小写,cased是意味着输入的词会保存其大写(在命名实体识别等项目上需要)。Multilingual是支持多语言的࿰…...
利用 ArcGIS Pro 快速统计省域各市道路长度的实操指南
在地理信息分析与处理的工作中,ArcGIS Pro 是一款功能强大的 GIS 软件,它能够帮助我们高效地完成各种复杂的空间数据分析任务。 现在,就让我们一起深入学习如何借助 ArcGIS Pro 来统计省下面各市的道路长度,这一技能在城市规划、…...
数据库系统概论(一)详细介绍数据库与基本概念
数据库系统概论(一)介绍数据库与基本概念 前言一、什么数据库1.数据库的基本概念2.数据库的特点 二、数据库的基本概念1. 数据2. 数据库3.数据库管理系统4.数据库系统 三、数据管理技术的产生和发展四、数据库系统的特点1.数据结构化2.数据共享性3.数据冗…...
数字IC后端实现教程| Clock Gating相关clock tree案例解析
今天小编给大家分享几个跟时钟树综合,clock tree相关的典型问题。 数字IC后端设计实现之分段长clock tree经典案例 Q1:星主好,下面的图是通过duplicate icg来解setup违例的示意图。我没看懂这个 duplicate操作在cts阶段是怎么实现的,用什么…...
build gcc
1,下载源码 wget https://gcc.gnu.org/pub/gcc/infrastructure/mpfr-4.1.0.tar.bz2 wget https://gcc.gnu.org/pub/gcc/infrastructure/gmp-6.1.0.tar.bz2 wget https://gcc.gnu.org/pub/gcc/infrastructure/mpc-1.2.1.tar.gz git clone --mirror https://github…...
软考架构师笔记-计算机网络
1.9 计算机网络 OSI/RM 七层模型 物理层 二进制传输(中继器、集线器) (typedef) 数据链路层 传送以帧为单位的信息(网桥、交换机、网卡) 网络层 分组传输和路由选择(三层交换机、路由器)ARP/RARP/IGMP/ICMP/IP 传输层 端到端的连接(TCP/UDP)在前向纠错系统中,当接…...
ubuntu打包 qt 程序,不用每次都用linuxdeployqt打包
用linuxdeployqt打包太麻烦,每次程序编译都要用linuxdeployqt打包一次,而且每次都要很长时间,通过研究得出一个新的打包方法 1.用用linuxdeployqt得出依赖的库文件(只要没有增加新模块,只要用一次就可以) …...
Spark(6)vm与centos虚拟机
(一)克隆虚拟机 vm软件提供了克隆的功能,它可以允许我们从一台虚拟机上快速克隆出其他的一模一样的主机。 具体的操作步骤如下: 关闭hadoop100这台虚拟机。在它身上右键,并选择管理 → 克隆 命令 在随后的设置中&#…...
人工智能开发面经AI、大数据、算法
以下是一份AI算法开发岗位的面试面经,结合最新行业趋势和经典问题,涵盖技术解析与实战案例,供参考: 一、机器学习基础(占比约30%) 1. 过拟合与欠拟合的解决方案 问题:如何解决模型过拟合&…...