最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Pass Data to Service in Axios - Stack Overflow

programmeradmin1浏览0评论

I want to set _boundry in my header.

First, I dispatch the form data:

//ponent.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?

I want to set _boundry in my header.

First, I dispatch the form data:

//ponent.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?

Share Improve this question edited Aug 8, 2021 at 19:17 ilvthsgm asked Aug 3, 2021 at 22:14 ilvthsgmilvthsgm 6361 gold badge10 silver badges30 bronze badges 0
Add a ment  | 

1 Answer 1

Reset to default 9

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();
    
    // attach files and other fields
    body.append("file", fileInput.files[0]);
    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.

const body = JSON.stringify({ foo: "foo", bar: "bar" });

// fetch
fetch(url, {
  method: "POST",
  headers: {
    "content-type": "application/json",
  },
  body
});

// XMLHttpRequest
const xhr = new XMLHttpRequest();
xhr.open("POST", url);
xhr.setRequestHeader("content-type", "application/json");
xhr.send(body);

On Axios

Axios will automatically stringify JavaScript data structures passed into the data parameter and set the Content-type header to application/json 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.

Axios v0.27.1 is broken

This specific version of Axios is unable to make a proper request with FormData. Do not use it!

Axios v1.0.0+ is broken

This is verging into my own opinion but every Axios release post v1.0.0 has been fundamentally broken in one way or another. I simply cannot remend anyone use it for any reason.

Much better alternatives are:

  • The Fetch API (also available in Node v18+)
  • got for Node.js
  • ky for browsers

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;
}, null, { synchronous: true });

or simply merge in the headers when making a request

axios.post(url, body, {
  headers: {
    "X-Any-Other-Headers": "value",
    ...body.getHeaders(),
  },
});

See https://github./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
})
发布评论

评论列表(0)

  1. 暂无评论