Webview2 Tauri 绕过 CORS

itemversion
tauri2.0.0-rc

前提

当你在 foo.com 使用 js 来访问 bar.com/api 的时候,你可能会遇到下面这样的错误(但你能够使用 curl 访问它):

Access to fetch at 'bar.com/api' 
from origin 'foo.com' has been blocked by CORS policy: 
No 'Access-Control-Allow-Origin' header is present on the requested resource. 
If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

首先你需要了解几个概念:

  1. 什么是 CORS

    https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS

  2. 什么是 CORS 预检请求,为什么在 js 中使用 fetch 等会会触发CORS检查?以及什么是 OPTION 操作?

    https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS#%E9%A2%84%E6%A3%80%E8%AF%B7%E6%B1%82

  3. 什么是简单请求,为什么简单请求不会触发CORS检查?

    https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS#%E7%AE%80%E5%8D%95%E8%AF%B7%E6%B1%82

  4. 为什么你在请求头中设置 Access-Control-Allow-Origin: * 无效?

    Access-Control-Allow-Origin 是一个响应头,在服务端设置。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers

如何在 Tauri 中解决这个问题

你可以在 js 中调用 rust 发送请求。但是我推荐你用官方的方案 @tauri-apps/plugin-http

安装依赖

pnpm add @tauri-apps/plugin-httppnpm add @tauri-apps/plugin-httppnpm add @tauri-apps/plugin-httppnpm add @tauri-apps/plugin-http
[dependencies]

tauri-plugin-http = "2.0.0-rc"

在 capabilities\default.json 中开启相应的权限

 "permissions": [
 "http:allow-fetch",
 "http:default",
 {
 "identifier": "http:default",
 "allow": [{ "url": "https://**" }]
 }

在 lib.rs 中注册该插件

tauri::Builder::default()
 .setup(|app| {
 ... // 省略
 })
 .plugin(tauri_plugin_shell::init()) // 其它插件
 .plugin(tauri_plugin_http::init()) // 本插件

https://v2.tauri.app/plugin/http-client

在前端调用(以 typescript 为例)

 import {fetch} from "@tauri-apps/plugin-http";

 /// fetch(...)