【问题标题】:fetch api return wrong response object获取 api 返回错误的响应对象
【发布时间】:2020-08-08 13:50:52
【问题描述】:

我正在使用 React js 中的 fetch api 向我的后端服务器发布请求

const formData = new FormData();
    formData.append("image", file);
    formData.append("userId", currentUser.id);
    formData.append("sliderNumber", sliderNumber);

    const myHeaders = new Headers();
    myHeaders.append("Content-Type", file.type);
    myHeaders.append("Aceess-Control-Allow-Origin", "*");

    fetch("http://localhost:4000/upload/slide-image", {
      method: "POST",
      headers: myHeaders,
      mode: "no-cors",
      body: formData
    })
      .then(response => response)
      .then(data => console.log("Printing data: ", data));
  };

在 Elixir 后端

def upload(conn, params) do
  # uploading code 

  #send response to the client with amazon s3 image url
  send_resp(conn, 200, image_url)
end

但是来自 fetch api 的响应对象是空的

Response {
  body: null
  bodyUsed: false
  headers: Headers {}
  ok: false
  redirected: false
  status: 0
  statusText: ""
  type: "opaque"
  url: ""
}

当我用状态码 400 响应时它不会改变。

似乎 fetch api 在某些时候没有正确构建 Reponse 对象。因为我可以在浏览器网络选项卡中找到正确的状态代码和响应正文。但是 Response 对象不保存来自后端服务器的响应。

有什么想法吗?

【问题讨论】:

  • 您期待来自服务器的 JSON 响应吗?
  • 当您使用"mode": "no-cors" 时,并非您指定的所有标头都被允许。检查developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch 了解更多信息。由于在标题中您允许使用 cors,我认为您可能意味着删除 "mode": "no-cors" 位。另外,.then(response => response) 可能还有其他意思。

标签: javascript fetch-api


【解决方案1】:

您的Content-Type 错误。与其他数据一起发送文件时,Content-Type 仍应为multipart/form-data

【讨论】:

    【解决方案2】:

    如果您希望服务器收到文本响应,那么在您的第一个 .then(.. 上,您应该这样做:

    fetch("http://localhost:4000/upload/slide-image", {
          method: "POST",
          headers: myHeaders,
          mode: "no-cors",
          body: formData
        })
          .then(response => response.text()) // <--- 
          .then(data => console.log("Printing data: ", data));
    

    fetch 返回一个解析为 Response 的 Promise。当您在此阶段使用.text() 时,您实际上所做的是获取响应流,将其读取到完成并返回将通过文本解析的承诺。

    除此之外,您还使用mode: "no-cors"(正如其他用户在他们的答案中提到的那样)在许多方面限制了您。例如,即使您按照我上面的说明进行操作,您也会得到一个空字符串,即使您尝试从服务器返回某些内容。这将是因为这种模式。

    您可以在 no-cors 下找到有关它的更多详细信息 here

    【讨论】:

      【解决方案3】:
       mode: "no-cors",
      

      您将模式设置为 no-cors,因此响应是不透明的,这意味着您看不到其中的内容。

      如果您需要阅读回复,请不要这样做。


      旁白:

      myHeaders.append("Content-Type", file.type);
      

      这是表单数据对象的错误内容类型。不要设置内容类型。 fetch API 会自动设置正确的。

         myHeaders.append("Aceess-Control-Allow-Origin", "*");
      

      Access-Control-Allow-Origin,您拼错了,是 响应 标头,而不是请求标头。

      .then(response => response)
      

      原封不动地返回响应是毫无意义的。如果你得到一个纯 URL,你可能想要response.text()

      【讨论】:

        【解决方案4】:

        接受的答案解决了我的问题。

        如果您期望来自后端的 JSON 对象,请使用

        .then((response) => response.json())
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-15
          • 2017-02-17
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多