POST 请求未将文件上传到服务器

Ven*_*son 14 javascript rest node.js reactjs

我被这个问题困扰了 3 天。我在前端使用 React.jsaxios并希望将文件上传到服务器。有一个 API 端点,它是一个像这样的后端点。

POST- https://88.66.123.122:20000/b1s/v1/Attachments2
Run Code Online (Sandbox Code Playgroud)

此端点基本上将文件上传到具有201状态的成功响应的服务器文件系统。当我使用桌面客户​​端测试端点时,响应成功正常Postman,此工具生成的代码片段是这样的。

邮递员片段

但我想在浏览器 UI 中实现这件事。所以我为此使用 React.js。

此端点还需要请求标头中的授权 cookie 以确保用户通过身份验证。因此,在 UI 中,我创建了一个登录按钮,该按钮基本上将带有硬编码凭据的 post 请求发送到login端点,并为我提供带有会话 ID 的成功响应。

我将浏览器中的会话 ID 保存为上传文件的 cookie,但是当我随请求发送 cookie 时,我在浏览器中收到以下响应

Refused to set unsafe header "Cookie"
Run Code Online (Sandbox Code Playgroud)

以及我用以下 JSON 返回的响应。

POST https://88.66.123.122:20000/b1s/v1/Attachments2 [401 (Unauthorized)]

{
   "error" : {
      "code" : 301,
      "message" : {
         "lang" : "en-us",
         "value" : "Invalid session."
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

我不知道我该如何解决这个问题?你可以看到GIF

代码:

import React from 'react';
import axios from 'axios';

const URL_LOGIN = `${process.env.REACT_APP_SERVER}Login`;
const COMPANY_DB = process.env.REACT_APP_DB;
const URL_ATTACHMENT = `${process.env.REACT_APP_SERVER}Attachments2`;
const CREDENTIALS = {
  UserName: process.env.REACT_APP_USERNAME,
  Password: process.env.REACT_APP_PASSWORD,
  CompanyDB: COMPANY_DB
};


function App() {
  const [isLogin, setIsLogin] = React.useState(false);
  const [selected, setSelected] = React.useState(null);

  function onClick() {
    setIsLogin(true);
    axios
      .post(URL_LOGIN, CREDENTIALS)
      .then(function (response) {
        setIsLogin(false);
        console.log(response.data);
      })
      .catch(function (err) {
        setIsLogin(false);
        console.log(err);
      });
  }

  // onUpload
  function handleUpload(event) {
    console.log('File set', event.target.files[0]);
    setSelected(event.target.files[0]);
  }

  function uploadSubmit() {
    const formData = new FormData();
    formData.append('files', selected, selected?.name);

    axios
      .post(URL_ATTACHMENT, formData)
      .then(function (response) {
        console.log('response', response);
      })
      .catch(function (err) {
        console.log('err', err);
      });
  }

  return (
    <div>
      <div>
        <button type="button" onClick={onClick} disabled={isLogin}>
          Login Create Cookie
        </button>
      </div>

      <hr />

      <div>
        <div>
          <input type="file" onChange={handleUpload} />
        </div>
        <button type="button" onClick={uploadSubmit}>
          Upload File
        </button>
      </div>
    </div>
  );
}

export default App;
Run Code Online (Sandbox Code Playgroud)

Ami*_*eem 9

cookie 由服务器管理,而不是客户端。在您的情况下,您使用的是带有HttpOnly标志的 cookie 。客户端脚本不允许您读取 Cookie 的值,因为它是一种安全威胁。

在您的 nodejs 应用程序中,服务器必须发送 Cookie 作为响应。服务器必须做这样的事情:

// nodejs (express)
res.cookie('cookieKey', "value", { maxAge: 900000, httpOnly: true });
Run Code Online (Sandbox Code Playgroud)

请注意 httpOnly 标志,该标志可防止客户端脚本使用 cookie。

一旦您设置了 cookie 以响应您的 NodeJs (Express) 请求,您的浏览器应该会自动开始随您的每个请求发送 Cookie。