跨域-告別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`**

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-個人思考
  1. 為什么有CORS跨域

    • 最簡單的解釋
      :前端和后端最好是部署在同一個服務器上,前后端之間使用內網IP進行訪問,避免后端的API接口被其他網站訪問(同源策略)。這個說法基本正確,但同源策略不僅是為了避免后端API被其他網站訪問,更是為了保護用戶的數據安全,防止惡意網站通過用戶瀏覽器竊取敏感信息。
    • 同源策略:瀏覽器的同源策略限制了一個文檔或腳本從一個源訪問另一個源的資源,除非滿足同源條件(協議、域名、端口都相同)。這是瀏覽器提供的一種安全機制,用于防止惡意網站讀取其他網站的敏感數據。
  2. 但我們為什么沒有這樣做

    • 多種原因
      • 前后端分離架構:現代Web開發中,前后端分離架構很常見,前端負責展示和交互,后端負責數據處理和業務邏輯,兩者通常部署在不同的服務器上。
      • 后端多實例容災:為了提高系統的可用性和可靠性,后端可能有多個實例部署在不同的服務器或數據中心,前端需要訪問不同的后端實例。
      • 其他元素:比如微服務架構,不同的服務可能部署在不同的服務器上,前端需要調用多個服務的API。
    • 前后端分析引發現象:前端必須使用IP或者域名進行訪問后端。這個說法不完全準確,前端可以通過多種方式訪問后端,比如通過域名、IP、負載均衡器等。
  3. 又引發運維上的問題

    • 后端的IP或者域名會變:確實,在實際運維中,后端的IP或者域名可能會因為各種原因發生變化,比如服務器遷移、負載均衡器調整等。
    • 但是前端又不能總是更換后端IP或者域名:這個說法正確,頻繁更換前端配置不現實,也不方便。
    • 一勞永逸的解決方案:后端直接全部放開API的接口調用。這個解決方案不安全,不能簡單地全部放開,否則會導致安全風險,比如跨站請求偽造(CSRF)攻擊、惡意爬蟲等。
  4. 域名不校驗豈不是要翻天

    • 解決方案
      • 前后端鑒權使用API-KEY或者其他鑒措施權:正確,通過API-KEY、OAuth、JWT等方式進行鑒權,可以確保只有授權的請求才能訪問后端API。
      • 公有云的防御服務:正確,公有云平臺提供了一系列的安全服務,比如防火墻、DDoS防護、WAF(Web應用防火墻)等,可以有效防止惡意攻擊。
  5. 那為什么我本地開發可以訪問很多網站的API接口

    • 因為開發人員沒有注意這些情況:這個說法不完全準確,很多網站的API是對外提供服務的,允許其他網站或開發者調用但,通常會有一些限制,比如需要注冊、申請API密鑰等。
    • 或者網站本身就是對外提供API訪問的網站:正確,比如一些開放平臺,如微博、微信等,它們的API就是對外提供服務的,供開發者集成到自己的應用中。
2-腦洞打開
  1. 開發側-如果我做靜態個人網站,我如何進行跨域限制(防止網站被惡意攻擊)

    • 跨域限制:可以通過設置CORS(跨域資源共享)策略來限制哪些網站可以訪問你的API。例如,在服務器配置中,只允許特定的域名訪問你的API。
    • 防止惡意攻擊:除了CORS,還可以采取其他安全措施,比如使用防火墻、限制請求頻率、使用驗證碼等。
  2. 開發側-如果我做SDK服務型網站,我如何進行跨域限制(防止網站被惡意攻擊)

    • 跨域限制:同樣可以通過CORS策略來限制訪問,還可以要求調用方提供API密鑰或其他身份驗證信息。
    • 防止惡意攻擊:可以對請求進行簽名驗證,確保請求的合法性;還可以對請求進行限流,防止惡意爬蟲或攻擊導致服務器過載。
  3. 爬蟲側-如和避免網站的API接口被爬取,如何定義自己的robots.txt

    • 避免被爬取:可以通過技術手段,比如限制請求頻率、驗證請求來源、使用驗證碼等,來防止惡意爬蟲。
    • 定義robots.txtrobots.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 不同源,端口號不相同
哪些操作不受同源策略限制
  1. 頁面中的鏈接,重定向以及表單提交是不會受到同源策略限制的;
  2. 跨域資源的引入是可以的。但是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-urlencodedmultipart/form-datatext/plain ] 類型

一個簡單的請求例子:

GET /test HTTP/1.1Accept: */*Accept-Encoding: gzip, deflate, sdch, brOrigin: http://www.examples.comHost: www.examples.com

對于簡單請求,CORS的策略是請求時在請求頭中增加一個Origin字段,服務器收到請求后,根據該字段判斷是否允許該請求訪問。

  1. 如果允許,則在 HTTP 頭信息中添加 Access-Control-Allow-Origin 字段,并返回正確的結果 ;
  2. 如果不允許,則不在 HTTP 頭信息中添加 Access-Control-Allow-Origin 字段 。

除了上面提到的 Access-Control-Allow-Origin ,還有幾個字段用于描述 CORS 返回結果 :

  1. Access-Control-Allow-Credentials: 可選,用戶是否可以發送、處理 cookie
  2. Access-Control-Expose-Headers:可選,可以讓用戶拿到的字段。有幾個字段無論設置與否都可以拿到的,包括:Cache-ControlContent-LanguageContent-Type
    ExpiresLast-ModifiedPragma
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 相關的字段有:

  1. 請求使用的 HTTP 方法 Access-Control-Request-Method
  2. 請求中包含的自定義頭字段 Access-Control-Request-Headers

服務器收到請求時,需要分別對 OriginAccess-Control-Request-MethodAccess-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

他們的含義分別是:

  1. Access-Control-Allow-Methods: 真實請求允許的方法
  2. Access-Control-Allow-Headers: 服務器允許使用的字段
  3. Access-Control-Allow-Credentials: 是否允許用戶發送、處理 cookie
  4. Access-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 處理過程如下:

  1. 判斷依據是 Header 中是否包含 Origin。如果包含則說明為 CORS請求,轉到 2;否則,說明不是 CORS 請求,不作任何處理。
  2. 判斷 responseHeader 是否已經包含 Access-Control-Allow-Origin,如果包含,證明已經被處理過了, 轉到 3,否則不再處理。
  3. 判斷是否同源,如果是則轉交給負責該請求的類處理。
  4. 是否配置了 CORS 規則,如果沒有配置,且是預檢請求,則拒絕該請求,如果沒有配置,且不是預檢請求,則交給負責該請求的類處理。如果配置了,則對該請求進行校驗。

校驗就是根據 CorsConfiguration 這個類的配置進行判斷:

  1. 判斷 origin 是否合法
  2. 判斷 method 是否合法
  3. 判斷 header是否合法
  4. 如果全部合法,則在 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需要處理跨域請求,并且希望有一個統一且全局的解決方案,那么使用WebMvcConfigurerCorsFilter
可能是更好的選擇。如果只需要在特定的Controller或方法上處理跨域請求,那么使用@CrossOrigin注解可能更為簡單直接。


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/71404.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/71404.shtml
英文地址,請注明出處:http://en.pswp.cn/web/71404.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

PE文件結構詳解(DOS頭/NT頭/節表/導入表)使用010 Editor手動解析notepad++.exe的PE結構

一&#xff1a;DOS部分 DOS部分分為DOS MZ文件頭和DOS塊&#xff0c;其中DOS MZ頭實際是一個64位的IMAGE_DOS——HEADER結構體。 DOS MZ頭部結構體的內容如下&#xff0c;我們所需要關注的是前面兩個字節&#xff08;e_magic&#xff09;和后面四個字節&#xff08;e_lfanew&a…

Node JS 調用模型Xenova_all-MiniLM-L6-v2實戰

本篇通過將句子數組轉換為句子的向量表示&#xff0c;并通過平均池化和歸一化處理&#xff0c;生成適合機器學習或深度學習任務使用的特征向量為例&#xff0c;演示通過NodeJS 的方式調用Xenova/all-MiniLM-L6-v2 的過程。 關于 all-MiniLM-L6-v2 的介紹&#xff0c;可以參照上…

【C++學習篇】智能指針

目錄 1. 智能指針的使用場景分析 2. RAII和智能指針的設計思路 3. C標準庫智能指針的使用 4.shared_ptr和weak_ptr 4.1shared_ptr的循環引用問題 4.2 weak_ptr 1. 智能指針的使用場景分析 下?程序中我們可以看到&#xff0c;new了以后&#xff0c;我們也delete了&#xff0c…

IntelliJ IDEA集成MarsCode AI

IntelliJ IDEA集成MarsCode AI IDEA中安裝插件 安裝完畢之后登錄自己的賬號 點擊鏈接&#xff0c;注冊賬號 https://www.marscode.cn/events/s/i5DRGqqo/ 可以選擇不同的模型

日期格式與字符串不匹配bug

異常特征&#xff1a;java.lang.IllegalArgumentException: invalid comparison: java.time.LocalDateTime and java.lang.String ### Error updating database. Cause: java.lang.IllegalArgumentException: invalid comparison: java.time.LocalDateTime and java.lang.Str…

C++中的無鎖編程

引言 在當今多核處理器普及的時代&#xff0c;并發編程已成為高性能應用程序開發的關鍵技術。傳統的基于鎖的同步機制雖然使用簡單&#xff0c;但往往會帶來性能瓶頸和死鎖風險。無鎖編程&#xff08;Lock-Free Programming&#xff09;作為一種先進的并發編程范式&#xff0c…

FastGPT 引申:借鑒 FastGPT 基于MySQL + ES 實現知識庫(含表結構以及核心代碼)

文章目錄 FastGPT 引申&#xff1a;借鑒 FastGPT 基于MySQL ES 實現知識庫&#xff08;含表結構以及核心代碼&#xff09;一、整體思路二、存儲結構2.1 MySQL 表結構(1) knowledge_base_dataset(2) knowledge_base_data(3) knowledge_base_index(4) ai_kb_relation 2.2 Elasti…

Python學習(十四)pandas庫入門手冊

目錄 一、安裝與導入二、核心數據結構2.1 Series 類型&#xff08;一維數組&#xff09;2.2 DataFrame 類型&#xff08;二維數組&#xff09; 三、數據讀取與寫入3.1 讀取 CSV 和 Excel 文件3.2 寫入數據 四、數據清洗與處理4.1 處理缺失值4.2 數據篩選4.3 數據排序 五、數據分…

【Python 數據結構 4.單向鏈表】

目錄 一、單向鏈表的基本概念 1.單向鏈表的概念 2.單向鏈表的元素插入 元素插入的步驟 3.單向鏈表的元素刪除 元素刪除的步驟 4.單向鏈表的元素查找 元素查找的步驟 5.單向鏈表的元素索引 元素索引的步驟 6.單向鏈表的元素修改 元素修改的步驟 二、Python中的單向鏈表 ?編輯 三…

第1章:項目概述與環境搭建

第1章&#xff1a;項目概述與環境搭建 學習目標 了解YunChangAction靈感記錄應用的整體架構和功能掌握SwiftUI開發環境的配置方法創建項目基礎結構并理解文件組織方式實現應用的啟動屏幕和基本主題設置 理論知識講解 靈感記錄應用概述 靈感記錄應用是一種專門設計用來幫助…

2025.3.3總結

周一這天&#xff0c;我約了績效教練&#xff0c;主要想了解專業類績效的考核方式以及想知道如何拿到一個更好的績效。其他的崗位并不是很清楚&#xff0c;但是專業類的崗位&#xff0c;目前采取絕對考核&#xff0c;管理層和專家崗采取相對考核&#xff0c;有末尾淘汰。 通過…

FastGPT 源碼:基于 LLM 實現 Rerank (含Prompt)

文章目錄 基于 LLM 實現 Rerank函數定義預期輸出實現說明使用建議完整 Prompt 基于 LLM 實現 Rerank 下邊通過設計 Prompt 讓 LLM 實現重排序的功能。 函數定義 class LLMReranker:def __init__(self, llm_client):self.llm llm_clientdef rerank(self, query: str, docume…

LeetCode 1745.分割回文串 IV:動態規劃(用III或II能直接秒)

【LetMeFly】1745.分割回文串 IV&#xff1a;動態規劃&#xff08;用III或II能直接秒&#xff09; 力扣題目鏈接&#xff1a;https://leetcode.cn/problems/palindrome-partitioning-iv/ 給你一個字符串 s &#xff0c;如果可以將它分割成三個 非空 回文子字符串&#xff0c;…

25年3月5日

1.思維導圖 2.不太會 #include "head.h" int main(int argc, const char *argv[]) {int fdopen("../xiaoxin.bmp","O_RDONLY");if(fd-1)printf("open error");//大小struct stat st;if(stat("…

全球首創!微軟發布醫療AI助手,終結手寫病歷時代

今天凌晨&#xff0c;微軟發布了醫療界首個用于臨床工作流程的AI助手Microsoft Dragon Copilot。 Dragon Copilot是基于語音文本的混合架構&#xff0c;能夠將醫生的語音或臨床口述內容實時轉換為文本。例如&#xff0c;醫生可以通過語音輸入患者的病歷信息、醫囑或診斷結果&a…

[自動駕駛-傳感器融合] 多激光雷達的外參標定

文章目錄 引言外參標定原理ICP匹配示例參考文獻 引言 多激光雷達系統通常用于自動駕駛或機器人&#xff0c;每個雷達的位置和姿態不同&#xff0c;需要將它們的數據統一到同一個坐標系下。多激光雷達外參標定的核心目標是通過計算不同雷達坐標系之間的剛性變換關系&#xff08…

Blazor-路由模板(下)

路由約束 類型約束 我們這里使用{id:int}限制路由&#xff0c;id為int類型&#xff0c;并且路由參數 id 對應的 Id 屬性也必須是 int 類型。我們試試能否正常訪問 page "/demoPage/{id:int}" <h3>demoPage</h3> <h2>路由參數Id&#xff1a;Id&l…

多線程-JUC源碼

簡介 JUC的核心是AQS&#xff0c;大部分鎖都是基于AQS擴展出來的&#xff0c;這里先結合可重入鎖和AQS&#xff0c;做一個講解&#xff0c;其它的鎖的實現方式也幾乎類似 ReentrantLock和AQS AQS的基本結構 AQS&#xff0c;AbstractQueuedSynchronizer&#xff0c;抽象隊列…

通過多線程獲取RV1126的AAC碼流

目錄 一RV1126多線程獲取音頻編碼AAC碼流的流程 1.1AI模塊的初始化并使能 1.2AENC模塊的初始化 ???????1.3綁定AI模塊和AENC模塊 ???????1.4多線程獲取每一幀AAC碼流 ???????1.5每個AAC碼流添加ADTSHeader頭部 ???????1.6寫入具體每一幀AAC的…

JVM常用概念之對象初始化的成本

在JVM常用概念之新對象實例化博客中我講到了對象的實例化&#xff0c;主要包含分配&#xff08;TLAB&#xff09;、系統初始化、用戶初始化&#xff0c;而我在JVM常用概念之線程本地分配緩沖區&#xff08;ThreadLocal Allocation Buffer&#xff0c;TLAB&#xff09;博客中也講…