如何通过Axios发送PDF并在Actix Web中接收

643ylb08  于 2023-10-18  发布在  iOS
关注(0)|答案(1)|浏览(102)

我试过很多种方法,但似乎都不起作用。我使用NextJS,所以首先我调用我的Next API:

...
      mutateUser(
        await fetchJson("/path/to/api", {
          method: "POST",
          headers: { "Content-Type": "application/pdf" },
          body: file, // const [file, setFile] = useState<File | null>(null);
        })
      );
...

然后,我在API中使用Axios调用ActixWeb服务器

...
  const { token } = req.session.user;
  const body = req.body;
  const api_url = `${process.env.SERVER_API_URL}/path/to/api` as string;
  console.log(body.length);

  try {
    const response = await axios.post(api_url, body, {
      headers: {
        Authorization: `Bearer ${token}`,
        "Content-Type": "application/pdf",
      },
    });
    res.json({ ...response.data, isLoggedIn: true });
  }
...

这就是我在Actix中的处理方式:

pub async fn route_function(db: Data<DatabaseRepository>, mut payload: Payload, auth: AuthorizationService) -> HttpResponse {
    let id = auth.id;
    let mut bytes = BytesMut::new();
    while let Some(item) = payload.next().await {
        bytes.extend_from_slice(&item.unwrap());
    }

    //bytes to string
    log::debug!("bytes: {:?}", bytes);
    // length of bytes
    log::debug!("bytes length: {:?}", bytes.len());

    let pdf_text = match pdf_extract::extract_text_from_mem(&bytes) {
        Ok(text) => text,
        Err(e) => { // PDF parsing error only with Axios
            log::error!("Error: {:#?}", e);
            return HttpResponse::BadRequest().json(ErrorResponse::new("error parsing pdf".to_string(), e.to_string()));
        }
    };
...

所以基本上,问题是这样的:当我使用Postman或cURL时,Rust路由工作得很好。下面是我的cURL命令供参考:

# This works
curl -X POST -H "Content-Type: application/pdf" -H "Authorization: Bearer <TOKEN>" --data-binary "@/path/to/file.pdf" http://localhost:8080/path/to/api

然而,当我使用Axios时,我得到一个PDF解析错误。PDF解析器库在解析PDF Trailer时返回错误。此外,我检查了请求的字节长度,当我使用Axios调用时,它大约是101k字节,但当我使用Postman或cURL调用时,它是58k字节。不知道为什么,但我认为这与它为什么不工作有关。这也让我觉得我在Axios、Next或Fetch上做错了什么,但我找不到哪里。我也试过使用FormData(),但也不起作用。
如果有人有一个变通办法,改变我的Actix路线,使它的工作一般,这也是赞赏。我只发现如何使用Payload提取器阅读pdf。
任何帮助都是感激不尽的。先谢了。

qij5mzcb

qij5mzcb1#

看来你接下来得做这个了

export const config = {
  api: {
    bodyParser: false,
  },
};

然后使用req作为可读流。
参考:https://github.com/vercel/next.js/issues/37735https://www.reddit.com/r/nextjs/comments/tt4qbf/getting_the_raw_request_body_according_to_next_is/
然后你可以使用axios发布这个。当您遇到进一步的问题时,您可能需要考虑设置Content-Length Header。
https://github.com/axios/axios/issues/5223#issuecomment-1690233615

相关问题