Skip to content

Commit

Permalink
release: v1.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
idootop committed Mar 24, 2024
1 parent 3597104 commit bc2c50e
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 49 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "tauri-plugin-cors-fetch"
version = "1.1.0"
description = "A Tauri plugin that enables seamless cross-origin resource sharing (CORS) for web fetch requests within Tauri applications."
version = "1.2.0"
description = "Enabling Cross-Origin Resource Sharing (CORS) for Fetch Requests within Tauri applications."
keywords = ["tauri", "CORS", "fetch"]
authors = [ "Del Wang <[email protected]>" ]
repository = "https://github.com/idootop/tauri-plugin-cors-fetch"
Expand Down
55 changes: 38 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,23 @@ An **unofficial** Tauri plugin that enables seamless cross-origin resource shari

## Overview

When developing cross-platform desktop applications with [Tauri](https://tauri.app), you may encounter CORS restrictions that prevent direct access to certain web resources, such as [OpenAI](https://openai.com/product) services. While the official [tauri-plugin-http](https://docs.rs/crate/tauri-plugin-http/latest) can achieve CORS bypassing, it requires adapting your network requests and may not be compatible with third-party dependencies.
When developing cross-platform desktop applications with [Tauri](https://tauri.app), you may encounter CORS restrictions that prevent direct access to certain web resources, such as [OpenAI](https://openai.com/product) services. While the official [tauri-plugin-http](https://docs.rs/crate/tauri-plugin-http) can achieve CORS bypassing, it requires modifying your network requests and may not be compatible with third-party dependencies that rely on the standard `fetch` API.

`tauri-plugin-cors-fetch` provides a transparent solution by automatically intercepting and modifying outgoing `fetch` requests, adding the necessary headers to bypass CORS restrictions. This allows you to continue using the standard `fetch` API without the need for additional code changes or workarounds.

**Features**

- **CORS Bypass**: Automatically handles CORS restrictions for `fetch` requests.
- **Seamless Integration**: Use the standard `fetch` API without modifications.
- **Flexible Configuration**: Enable CORS globally or on a per-request basis.

## Installation

Add the plugin to your Tauri project's dependencies:
1. Add the plugin to your Tauri project's dependencies:

```shell
# src-tauri
cargo add tauri-plugin-cors-fetch
```

Then, initialize the plugin in your Tauri application setup:
2. Initialize the plugin in your Tauri application setup:

```rust
// main.rs
// src-tauri/main.rs
fn main() {
tauri::Builder::default()
.plugin(tauri_plugin_cors_fetch::init())
Expand All @@ -38,23 +33,48 @@ fn main() {
}
```

3. Add permissions in your `capabilities` configuration:

```json
// src-tauri/capabilities/default.json
{
"permissions": ["cors-fetch:default"]
}
```

4. Enable `withGlobalTauri` in your Tauri configuration:

```json
// src-tauri/tauri.conf.json
{
"app": {
"withGlobalTauri": true
}
}
```

## Usage

After installing and initializing the plugin, you can start making `fetch` requests from your Tauri application without encountering CORS-related errors.

```javascript
// For global configuration (default is true when the app starts)
// Enable CORS for the hooked fetch globally (default is true on app start)
window.enableCORSFetch(true);

// Use the hooked fetch
// Use the hooked fetch with CORS support
fetch("https://example.com/api")
.then((response) => response.json())
.then((data) => console.log(data))
.catch((error) => console.error(error));

// Or, explicitly call window.corsFetch (even if the global switch is off)
window.corsFetch("https://example.com/api");
// Use the hooked fetch directly
window.hookedFetch("https://example.com/api");

// Use the original, unhooked fetch
window.originalFetch("https://example.com/api");
```

Note: To allow requests, you may need to enable `withGlobalTauri` and update your Content Security Policy (CSP) to include `x-http` and `x-https` protocols:
Note: To allow requests, you may update your Content Security Policy (CSP) to include `x-http` and `x-https` protocols:

```json
// src-tauri/tauri.conf.json
Expand All @@ -74,8 +94,9 @@ This plugin registers custom `x-http` and `x-https` protocols for Tauri applicat

## Limitation

1. Requires Tauri version 2.0 or later. Only desktop platforms are supported; iOS and Android have not been tested.
2. Does not support `XMLHttpRequest` (XHR) requests. It is designed specifically to work with the modern `fetch` API.
1. **No Custom CSP Policy Support**: By default, all HTTP/HTTPS requests will be redirected to local native requests.
2. **No XMLHttpRequest Support**: The plugin is designed specifically to work with the modern `fetch` API and does not support `XMLHttpRequest` (XHR) requests.
3. **No Mobile Platform Support**: Only desktop platforms are supported; iOS and Android have not been tested.

## License

Expand Down
50 changes: 20 additions & 30 deletions api-iife.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,37 @@
class CORSFetch {
_fetch;
_request_id = 1;

constructor() {
this._fetch = fetch.bind(window);
window.fetch = this._hookFetch.bind(this);
window.originalFetch = fetch.bind(window);
window.hookedFetch = this.hookedFetch.bind(this);
this.enableCORS(true);
}

_enableCORS = true;
enableCORS(enable) {
this._enableCORS = enable;
window.fetch = enable ? window.hookedFetch : window.originalFetch;
}

async _hookFetch(input, init) {
return this.corsFetch(input, init, this._enableCORS);
}

async corsFetch(input, init, cors = true) {
let id = 0;
async hookedFetch(input, init) {
let url = input instanceof Request ? input.url : input.toString();
const shouldCORS = cors && /^(?:x-)?https?:\/\//i.test(url);
if (shouldCORS) {
if (!url.startsWith("x-")) {
url = "x-" + url;
}
id = this._request_id++;
init = {
...init,
headers: {
...init?.headers,
"x-request-id": id.toString(),
},
};
if (!/^(?:x-)?https?:\/\//i.test(url)) {
return window.originalFetch(input, init);
}

if (!url.startsWith("x-")) {
url = "x-" + url;
}
const id = this._request_id++;
init = {
...init,
headers: {
...init?.headers,
"x-request-id": id.toString(),
},
};
try {
const response = await this._fetch(url, init);
const response = await window.originalFetch(url, init);
return response;
} catch (error) {
if (id) {
await this._invoke("plugin:cors-fetch|cancel_cors_request", { id });
}
await this._invoke("plugin:cors-fetch|cancel_cors_request", { id });
return error;
}
}
Expand All @@ -52,6 +43,5 @@ class CORSFetch {

(function () {
const cf = new CORSFetch();
window.corsFetch = cf.corsFetch.bind(cf);
window.enableCORSFetch = cf.enableCORS.bind(cf);
})();
Binary file modified banner.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit bc2c50e

Please sign in to comment.