【问题标题】:Pass Data to Service in Axios在 Axios 中将数据传递给服务
【发布时间】:2021-10-09 02:09:51
【问题描述】:

我想在标题中设置_boundry

首先,我发送表单数据:

//component.js

const form = new FormData();

form.append('email', 'eray@serviceUser.com')
form.append('password', '12121212')

dispatch(FetchLogin.action(form))

第二,我准备api调用;

//loginService.js

import api from '@/Services'

export default async form => {
  const response = await api.post('user/login/', form)
  return response.data
}

第三,我调用api;

//Services/index.js

import axios from 'axios'
import { Config } from '@/Config'

const instance =  axios.create({
  baseURL: Config.API_URL,
  headers: {
    'Content-Type': `multipart/form-data; boundary=${form._boundary}`, //Cannot access form here
  }, 
  timeout: 3000,
})

instance.interceptors.response.use(
  response => response,
  ({ message, response: { data, status } }) => {
    return handleError({ message, data, status })
  },
)

export default instance

我想访问axios instance 中的form 数据,以便能够在headers 中使用form._boundry

如何将form 数据从loginService.js 传递到Services/index.js

【问题讨论】:

    标签: javascript react-native axios multipartform-data form-data


    【解决方案1】:

    这个问题似乎经常出现,但我似乎找不到一个规范的答案,所以这里......

    当从浏览器(通过fetchXMLHttpRequest)执行AJAX 请求时,运行时知道如何处理某些请求正文格式,并会自动设置适当的Content-type 标头

    • 如果请求正文是 FormData 实例,则 Content-type 将设置为 multipart/form-data 并且还将包括来自数据实例的适当的 mime 边界标记。

      所有这些示例都会将数据发布为multipart/form-data,并带有适当的mime boundary tokens

      const body = new FormData()
      body.append("foo", "foo")
      body.append("bar", "bar")
      
      // fetch
      fetch(url, { method: "POST", body })
      
      // XMLHttpRequest
      const xhr = new XMLHttpRequest()
      xhr.open("POST", url)
      xhr.send(body)
      
      // Axios
      axios.post(url, body)
      
    • 如果请求正文是URLSearchParams 实例,则Content-type 将设置为application/x-www-form-urlencoded

      所有这些示例都会将数据发布为application/x-www-form-urlencoded

      const body = new URLSearchParams({ foo: "foo", bar: "bar" })
      // serialises to "foo=foo&bar=bar"
      
      // fetch
      fetch(url, { method: "POST", body })
      
      // XMLHttpRequest
      const xhr = new XMLHttpRequest()
      xhr.open("POST", url)
      xhr.send(body)
      
      // Axios
      axios.post(url, body)
      

    如果您打算发送特定格式的字符串数据,例如text/xmlapplication/json 等,您只需要手动设置Content-type,因为运行时无法从数据中推断出类型。

    fetch(url, {
      method: "POST",
      headers: {
        "Content-type": "application/json",
      },
      body: JSON.stringify({ foo: "foo", bar: "bar" })
    })
    

    在 Axios 上

    Axios 为POSTPUTPATCH 请求提供Accept: application/jsonContent-type: application/json 的默认值。它还会自动对传递给data 参数的JavaScript 数据结构进行字符串化,因此在处理JSON API 时只需要最少的配置

    // no extra headers, no JSON.stringify()
    axios.post(url, { foo: "foo", bar: "bar" })
    

    在底层,Axios 使用XMLHttpRequest,因此FormDataURLSearchParams 的规范也适用。

    NodeJS

    从后端使用 Axios 时,它不会从 FormData 实例推断 Content-type 标头。您可以使用请求拦截器解决此问题。

    axios.interceptors.request.use(config => {
      if (config.data instanceof FormData) {
        Object.assign(config.headers, config.data.getHeaders());
      }
      return config;
    }, null, { synchronous: true });
    

    https://github.com/axios/axios#form-data


    关于 jQuery $.ajax()

    jQuery 的$.ajax() 方法(以及$.post() 等便捷方法)默认以application/x-www-form-urlencoded 发送请求正文有效负载。 JavaScript 数据结构将使用jQuery.param() 自动序列化,除非被告知不要。如果希望浏览器根据正文格式自动设置Content-type标头,还需要在options中进行配置

    const body = new FormData()
    body.append("foo", "foo")
    body.append("bar", "bar")
    
    $.ajax({
      url,
      method: "POST",
      data: body,
      contentType: false, // let the browser figure it out
      processData: false  // don't attempt to serialise data
    })
    

    【讨论】:

    • 感谢您的详细解答。我看到我不必像你提到的那样在 Axios 中定义标题,这很棒!但是你的回答并不能解决我的问题。我仍然无法正确发布formData。如果我在我的组件中发布 formData 而没有 header 作为您的答案,那么一切都很好。但是如果我dispatchformDataAxios 使用默认标题发布:"Content-Type": "application/x-www-form-urlencoded"。这个问题可能与Redux 有关。
    • @ilvthsgm 这很奇怪。您能否请edit your question 展示您的减速器和任何中间件(sagas / thunk / 等)是如何连接的?
    • 我的网址中有多余的/,这就是问题所在。感谢您的帮助。
    猜你喜欢
    • 2016-08-21
    • 1970-01-01
    • 2014-01-25
    • 1970-01-01
    • 2019-03-16
    • 2018-05-10
    • 1970-01-01
    相关资源
    最近更新 更多