Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
391 views
in Technique[技术] by (71.8m points)

javascript - Pass Data to Service in Axios

I want to set _boundry in my header.

First, I dispatch the form data:

//component.js

const form = new FormData();

form.append('email', '[email protected]')
form.append('password', '12121212')

dispatch(FetchLogin.action(form))

Second, I prepare api call;

//loginService.js

import api from '@/Services'

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

Third, I make api call;

//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

I want to access form data within to axios instance to be able to use form._boundry in headers.

How can I pass form data from loginService.js to Services/index.js?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This question seems to come up often enough yet I cannot seem to find a canonical answer so here goes...

When performing AJAX requests from a browser (via fetch or XMLHttpRequest), the runtime knows what to do for certain request body formats and will automatically set the appropriate Content-type header

  • If the request body is a FormData instance, the Content-type will be set to multipart/form-data and will also include the appropriate mime boundary tokens from the data instance.

    All of these examples will post the data as multipart/form-data with appropriate 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)
    
  • If the request body is a URLSearchParams instance, the Content-type will be set to application/x-www-form-urlencoded

    All of these examples will post the data as 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)
    

You only need to manually set the Content-type if you intend to send string data in a particular format, eg text/xml, application/json, etc since the runtime cannot infer the type from the data.

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

On Axios

Axios provides defaults of Accept: application/json and Content-type: application/json for POST, PUT and PATCH requests. It will also automatically stringify JavaScript data structures passed into the data parameter so you only need minimal configuration when dealing with JSON APIs

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

Under the hood, Axios uses XMLHttpRequest so the specifications for FormData and URLSearchParams also apply.

NodeJS

When using Axios from the backend, it will not infer Content-type headers from FormData instances. You can work around this using a request interceptor.

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

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


On jQuery $.ajax()

jQuery's $.ajax() method (and convenience methods like $.post()) default to sending request body payloads as application/x-www-form-urlencoded. JavaScript data structures will be automatically serialised using jQuery.param() unless told not to. If you want the browser to automatically set the Content-type header based on the body format, you also need to configure that in the 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
})

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...