添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
小胡子的数据线  ·  使用Aurora ...·  7 月前    · 
健壮的李子  ·  中国经济周刊·  7 月前    · 

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Try to send request with content type application/x-www-form-urlencoded

var data = Querystring.stringify({ 
                "grant_type": "password",
                "username": login,
                "password": password
axios.post(Urls.login, data);

but there is no such header in request.

I tried to use code:

  var data = Querystring.stringify({ 
                "grant_type": "password",
                "username": login,
                "password": password
        return axios({
            method: 'post',
            url: Urls.login,
            data: data,
            headers: {
                'Content-type': 'application/x-www-form-urlencoded'

same problem

jquery code works fine:

$.ajax({
            url: Urls.login,
            data: data,
            type: "POST",
            headers: {
                'Content-type': 'application/x-www-form-urlencoded'

How can I use axios to send request with this header?

ksarien, montnyc, taverasmisael, radupotop, mifi, elado, kennethross, michaeldzjap, wwwxy80s, Luomusha, and 78 more reacted with thumbs up emoji TotooriaHyperion, awave1, rimiti, LLily7, and liuhongpeng reacted with hooray emoji hatemalimam, MaksimKiselev, postb99, and JerryCram21 reacted with confused emoji SumeetGohil, rimiti, LLily7, and zacharytyhacz reacted with heart emoji All reactions

The cause is interceptors. I can't send request with that Content-Type only when I use interceptors.

Here is my code:

axios.interceptors.request.use(function (config) {
        var token = LoginStore.getJwt();
        if (token) {
            config.headers["Authorization"] = "Bearer " + token;
            return config;
        }, function (error) {    
            return Promise.reject(error);

Inside interceptor I can see 'Content-Type' header, but it is not sent to the server.
Do I correctly use interceptors?

This seems to be the culprit line → https://github.com/mzabriskie/axios/blob/master/lib/adapters/xhr.js#L117

Any idea why the Content-Type header is removed before the request is sent?

A workaround option is to change your data to data || {} when you're making an axios request. This will make sure data is not undefined.

jbsmith731, khirayama, wwwxy80s, yatoo1993, yanlp, shuangq, perry-mitchell, yesvods, lisaShen91, jacekkarczmarczyk, and 4 more reacted with thumbs up emoji yatoo1993 reacted with heart emoji All reactions

It looks like the logic for removing Content-Type when requestData is undefined came in this commit 9096d34. There is no indication why it was added however.

I would vote if the requestData is undefined and method is PUT, POST or PATCH and no Content-Type has been set, then default Content-Type to application/x-www-form-urlencoded. Otherwise just honor whatever has been specified.

@mzabriskie I think you're right. When I use request interceptor fiddler shows that data is empty. Without interceptor I can see data and header and it works fine.

So, probably the problem occurs when you work with interceptors.

No interceptor is needed to crash this thing. I've set content type header defaults axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';, and i can't send any payload in POST body.

I've used workaround with URLSearchParams:

    var params = new URLSearchParams();
    params.append('email', email);
    return (dispatch) => {
        axios.post('/stack/' + uri, params)

But this is not supported by Safari and IE.

Edit: Okay :) Next update on workaround. Full supported workaround is send data as query string.
data: "flashcard=" + JSON.stringify(flashcard) + "&stackUri=" + stackUri. It hurts, but it works 👍

WLyKan, iceberg211, ZeviLiao, jermainedilao, selfeik, spehlivan, divmgl, gustavlsouz, agrawalmitesh, and zacharytyhacz reacted with thumbs up emoji weituotian and eldyvoon reacted with thumbs down emoji kamil-kielczewski, divmgl, and gustavlsouz reacted with hooray emoji All reactions silasrm, gabrielmicko, ai-zuo, sebkolind, santosguilherme, tresko, adrivelasco, lilangxiong, lvxiaowu, 94xxh, and 44 more reacted with thumbs up emoji cristian-eriomenco, michaelwitk, cadavre, luq10, 0x8801, joshlangner, SoaresMG, sejolopab, polyakoff, Sunny-fr, and 78 more reacted with thumbs down emoji leonardobaggio, uysalut, tanmengmeng, ai-zuo, adrivelasco, sRect, Brhernann, Annihil, awave1, arfaWong, and 7 more reacted with laugh emoji ayashaswini2, adrivelasco, dsteinel, Brhernann, Annihil, ntkzwane, arfaWong, lacajanegra, ArthurWirbel, DmGolovchenko, and 5 more reacted with heart emoji renatoaug, Ash-Kay, HakurouKen, Juanperezc, and chinz100 reacted with rocket emoji All reactions

I use a interceptor with qs library to solve this problem. Works fine for me.

import qs from 'qs';
axios.interceptors.request.use((request) => {
  if (request.data && request.headers['Content-Type'] === 'application/x-www-form-urlencoded') {
      request.data = qs.stringify(request.data);
  return request;
  towersxu, rodrigogs, lmarqs, emkman, hhhuaang, mufasa71, and shmuli9 reacted with thumbs up emoji
  joshlangner, matrunchyk, bxyoung, Oxicode, amakh, DavidJiang7, sjf1256754123, damianprzygodzki, humiston, moshanghan, and 12 more reacted with thumbs down emoji
    All reactions
  vste23, rodcox89, luq10, joshlangner, sejolopab, polyakoff, matrunchyk, kostia1st, narek11, sebkolind, and 50 more reacted with thumbs up emoji
  leoneed96, huowenxuan, adi23arora, joshuakcockrell, Thinkpad93, rimiti, syysmile, and mohamed351 reacted with confused emoji
  damianprzygodzki, joshlangner, matrunchyk, sebkolind, diegoazh, joshuakcockrell, Thinkpad93, and mohamed351 reacted with heart emoji
    All reactions

hyanmandian commented 14 hours ago
I use a interceptor with qs library to solve this problem. Works fine for me.

Great, but it is not a way to solve issue in libraries IMHO by installing another.

usaaama2010, akakoori, daverogers, earllapura, shazul, joshuakcockrell, edwinharly, Tymek, bjackson, and dbeff reacted with thumbs up emoji usaaama2010 and joshuakcockrell reacted with heart emoji All reactions

You can just add a data: {} to the config, so the interceptor doesn't skip the headers which we specify.

This is what I did, and it worked for me:

import request from 'axios'
export const playSound = (soundFile) => (dispatch) => {
	dispatch(playSoundPending());
	return request
    .get(`/play/audio/${soundFile}`, { headers: {'Content-Type': 'audio/x-wav'}, data: {} })
    .then(response => response.data)

This changed the Content-Type from application/json to audio/x-wav for me in the request headers in the network tab.

luq10, holer-h, DerekTso, afreeland, HyunmoAhn, mort3za, chenly1, 780035023, BoyBoBo, mrichar1, and TonyRise reacted with thumbs up emoji chenly1, cabezayunke, diegoazh, NILISSSSSSSSSSSSSSSSS, hqxf, and anilabsinc-harpreet reacted with thumbs down emoji afreeland, chenly1, junhan566, and hqxf reacted with hooray emoji chenly1 and hqxf reacted with confused emoji All reactions

I solved the problem using encodeURIComponent:

static getToken(username, password) {
return axios({
method: 'post',
url: 'endpoints',
data: Username=${**encodeURIComponent**(username)}& password=${**encodeURIComponent**(password)}& Grant_type=password

I moved to isomorphic-fetch for this particular request as a workaround.
Things seem to work OK on most browsers, but still not working on certain Safari versions.
I am begining to think that Safari is screwing me.

I've actually had to create yet another messy hybrid app by using fetch in browsers and axios in node and within react-native. Seems funny that it's like this and not the other way around. Really hoping to see this tackled soon so I can remove my monkey-patch.

I think it's important to realise that this is definitely not only an issue with querystring.. My body content is just raw text with no parameters, yet I can't send it using axios with a Content-Type.

I created a PR that would fix the problem over two months ago... I don’t understand why it not get merged?!

Keep in mind that no one has pushed anything since september last year, maybe they're searching for maintainers?. Also, I think you missed a test when I compare your PR with: https://github.com/axios/axios/pull/1544/files

@mzabriskie could you maybe take the responsibility to merge one of these PR's? As currently some software requires get requests to have a content-type set (RoR params for instance: https://guides.rubyonrails.org/api_app.html#using-actiondispatch-request). The solution specified in #362 (comment) seems like the proper way to go and it would most of all solve all the desperate hacks like using fetch for this specific use case.

perry-mitchell, bertolo1988, rommyarb, damianprzygodzki, and dawidjaniga reacted with thumbs up emoji gazdagergo, xzessmedia, bertolo1988, guikubivan, leslie-alldridge, and aladushkaoya reacted with confused emoji All reactions

Wow... they should just abandon the project at this point, I know I am. Almost 3 years since issue originally reported and now we're still trying to solve this thing? Unbelievable. I love open source so I'm not harboring any ill feelings for this project not have maintainers but... it's used by TONS of people so the least you could do is abandon it so we all know this project is dead/dying. Thanks.

@kslr got or request seems like what everyone else has started migrating too. I'm trying to stick with Axios but I think it'll end up just coming down to me writing some abstraction layer over it so I can swap out the underlying HTTP request library and then if I use a different library which has a "built-in" HTTP client it uses, just let it do its thing.

I tried something like this and worked for me.
Maybe not the best solution but it can really help (i think), any suggestion, if this solution is horrible, is welcome.

const foo= yield qs.stringify({ 'grant_type' : 'yourGrantType', 'param' : param, 'param' : param }) const bar= yield axios.post('/baz', foo)

I have removed the header, and it seems like it has received well.

I had two problems using RoR as backend.

My context:

I had a project using deprecated vue-resource and everything works ok without additional config. And now, I'm organizing the project's dependencies and replacing deprecated dependencies, so I replaced vue-resource with axios ;)...

But, we had some problems and below I will share what I do to solve these problems. Maybe help someone! So sorry if I haven't helped you as you expected

First problem, the problem is the same as this issue, I solved using:

axios.interceptors.request.use(config => {
  config.paramsSerializer = params => qs.stringify(params);
  return config;
});

Now, params like:

search: "Something", sort: "asc",

will be transformed to:
http://xxxx/?q%5Bsearch%5D=something&q%5Bsort%5D=asc

this parsed will be:

q[search]: something
q[sort]: asc

Second problem, RoR is returning HTML response instead of JSON response:

This problem occurs because our backend must distinguish AJAX requests from other types of requests.

By default, vue-resource already set X-Requested-With header as expected. But, axios not. So, I had to define this key in the request header. My Axios global config was as follows in the end:

axios.interceptors.request.use(config => {
  config.paramsSerializer = params => qs.stringify(params);
  return config;
});
axios.defaults.headers.common['Accept'] = 'application/json';
axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

If you use Rails as backend and no one of the solutions worked for you, let me know, maybe I help you =).

Am working on react-native and getting bad request 400 error when use this :
import * as qs from 'querystring';
axios.post(url,qs.stringify({
'first_name': 'deep',
'last_name': 'palotra',
headers : {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}).then((response)=>{
console.log('worked')
}).catch((error)=>{
console.log('error')
console.log(error)

Sad to see that so many people are confused in this issue. I have try my best to read those comments. But it seems to have involved many other problems.

Everyone, forgive me to close it. If someone can open a new issue to describe the problem clearly, that will be really big thanks to you.

Hey everyone,

I thought I'd chime in as I wasted almost a full working day of my life trying to solve this. This may help some partially, or completely so here's to hoping this is useful.

My reply stems from seeing various reasons why a POST was failing with Axios ranging from:

  • 400 Bad Request
  • Can't post with custom Headers (like this thread)
  • Need to serialize/stringify the data/payload
  • I was facing the same issue as everyone in this thread with the Bad Request 400 when passing in custom headers to Axios in the config like this, and tried many of the responses here, like using qs.stringify(), setting data in the config to null or {} to no avail.

    Note - Adding the .catch() block and logging the error like so really helped me because I was able to surface an error that wasn't so cryptic. I was able to use the message to debug and ultimately figure out the issue I was having.

    It's important in the .then() block to return response.data, otherwise you'll run into this error:

    Converting circular structure to JSON

    Now my issue was the api POST body was not what the endpoint wanted, but I couldn't see it until I was able to log the error.

    Further, I'm also using NestJS and the HttpService, which is a wrapper around Axios, and that further complicated the issue because the real error wasn't bubbling up in the catchError callback in my pipe.

    So here is the solution for both pure Axios and NestJS.

    Axios:

    const headers = { 'Content-Type': 'application/x-www-form-urlencoded' };
    return axios.post('https://some-made-up-endpoint, dataString, { headers })
    .then(resp => resp.data)
    .catch(error => {
    this.logger.log('ERROR: ${JSON.stringify(error.response.data)}');

    NestJS:

    const headers = { 'Content-Type': 'application/x-www-form-urlencoded' };
    return this.http.post('https://some-made-up-endpoint, dataString, { headers }).pipe(
    map(response => response.data), // This is important otherwise - circular JSON error
    catchError((error: any) => {
    this.logger.error('[[[[ ERROR TRYING TO FETCH TOKEN: ${error.message} ]]]]');
    return of()
    ).toPromise();

    TLDR;

  • Add the .catch() block to properly log the real error, otherwise it's 400 Bad Request
  • Make sure your data signature matches what the API is expecting. This is part of the reason an error exists since a code 400 is a 'Bad Request'
  • Return the response.data in the .then() block if you're using Axios, or in a map operator if you're using NestJS or you'll get the Converting circular JSON error
  • Sorry for the long post and good luck everyone!

    Cheers

    Am working on react-native and getting bad request 400 error when use this :
    import * as qs from 'querystring';
    axios.post(url,qs.stringify({
    'first_name': 'deep',
    'last_name': 'palotra',
    headers : {
    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
    }).then((response)=>{
    console.log('worked')
    }).catch((error)=>{
    console.log('error')
    console.log(error)

    this work for me. with query stringfy thanks a lot.
    you save my live

    You can use a library like qs instead:

    var qs = require('qs');
    axios.post('/foo', qs.stringify({ 'bar': 123 });

    Your solution is working. Thanks a lot!