tauri-apps / plugins-workspace

All of the official Tauri plugins in one place!
https://tauri.app
Apache License 2.0
979 stars 274 forks source link

[bug] http服务器设置头 Transfer-Encoding: chunked 后,fetch失败 #1957

Open buff-m opened 1 month ago

buff-m commented 1 month ago

Describe the bug

当我http服务器设置了发送头 Transfer-Encoding: chunked 属性后,fetch 请求失败 因为我的数据比较大,需要分块发送给客户端

Reproduction

No response

Expected behavior

No response

Full tauri info output

> zhiyun_tools@0.1.0 tauri
> tauri "info"

[✔] Environment
    - OS: Windows 10.0.22631 x86_64 (X64)
    ✔ WebView2: 129.0.2792.89
    ✔ MSVC: 
        - Visual Studio 15 生成工具 2017
        - Visual Studio Community 2019
        - Visual Studio Community 2022
    ✔ rustc: 1.82.0 (f6e511eec 2024-10-15)
    ✔ cargo: 1.82.0 (8f40fc59f 2024-08-21)
    ✔ rustup: 1.27.1 (54dd3d00f 2024-04-24)
    ✔ Rust toolchain: stable-x86_64-pc-windows-msvc (default)
    - node: 17.9.1
    - yarn: 1.22.21
    - npm: 8.11.0

[-] Packages
    - tauri 🦀: 2.0.4
    - tauri-build 🦀: 2.0.1
    - wry 🦀: 0.46.2
    - tao 🦀: 0.30.3
    - tauri-cli 🦀: 2.0.3
    - @tauri-apps/api : 2.0.2
    - @tauri-apps/cli : 2.0.3

[-] Plugins
    - tauri-plugin-log 🦀: 2.0.1
    - @tauri-apps/plugin-log : not installed!
    - tauri-plugin-http 🦀: 2.0.1
    - @tauri-apps/plugin-http : 2.0.0
    - tauri-plugin-fs 🦀: 2.0.1
    - @tauri-apps/plugin-fs : not installed!

[-] App
    - build-type: bundle
    - CSP: unset
    - frontendDist: ../dist
    - devUrl: http://localhost:8080/
    - framework: Vue.js (Vue CLI)
    - bundler: Webpack

Stack trace

No response

Additional context

No response

FabianLars commented 1 month ago

Are we talking about the browser's built-in fetch or the fetch function from tauri's http plugin?

buff-m commented 1 month ago

@FabianLars 在tauri的http plugin中的fetch函数

amrbashir commented 1 month ago

@buff-m can you give an example or a minimal repro I can use?

buff-m commented 1 month ago

@amrbashir`` 这是服务器代码例子,它是用uWebSockets写成的

#include "App.h"
#include <iostream>

int main()
{
    auto *loop = uWS::Loop::get();
    uWS::App app = uWS::App();

    app.get("/", [](auto* res, auto* req) {
        res->writeHeader("Content-Type", "text/plain");
        res->writeHeader("Transfer-Encoding", "chunked");

        res->write("H");
        res->write("e");
        res->write("l");
        res->write("l");
        res->write("o");

        res->end();
    });
    app.listen(3808, [](auto* token) { std::cout << "Listening on port 3808\n"; });

    loop->run();

    return 1;
}

当我使用其他工具,比如浏览器自带的 fetch function 或者 postman 请求数据时,能够正常获取到 hello,当我使用 tauri's http plugin 的 fetch function 请求数据时,它失败了提示 “error sending request for url (http://localhost:3808/)” 。

当我注释掉 res->writeHeader("Transfer-Encoding", "chunked"); 时,浏览器的 fetch 和 http plugin 的 fetch 都能获取到正常的数据 hello

lloydzhou commented 3 weeks ago

可以参考 https://github.com/tauri-apps/plugins-workspace/issues/1002#issuecomment-2382206860 这里提到的一个替代方案,这个方案支持在tauri内使用fetchEventSource调用LLM的API接口。

amrbashir commented 3 weeks ago

@buff-m I can't unfortunately use a c++ example, as that took a long time for me to setup and yet I can't get it to work. If you have a server in JS or Rust, I will be happy to take a look.

lloydzhou commented 3 weeks ago

js version

const express = require('express')
const app = express()
const port = 3000

app.get('/', (req, res) => {
  let counter = 0;
  const interval = setInterval(() => {
    if (counter > 10) {
      clearInterval(interval);
      res.end()
    }
    const chunk = JSON.stringify({chunk: counter++});
    res.write(`data: ${chunk}\n\n`);
  }, 1000);
})

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`)
})
amrbashir commented 3 weeks ago

@lloydzhou thanks for the server code, I tested the http plugin with that and it works well