Semblable Ă #318 , je ne parviens pas Ă faire une demande de publication avec axios sur node. Mais sur le navigateur, le mĂȘme morceau de code semble fonctionner correctement.
const fdata = new FormData();
fdata.append('user', u);
fdata.append('hostnames', n.join(' '));
const host = localStorage.getItem('host');
const port = localStorage.getItem('port');
axios({
url: `http://${host}:${port}/hosts/remove`,
method: 'post',
data: fdata
}).then(response => {
if (response.status === 200) {
console.log(response.data);
console.log('Removed host successfully');
}
return null;
}).catch(er => console.log(er));
Avec unirest ça marche :
unirest.post(`http://${host}:${port}/hosts/remove`)
.headers({ 'Content-Type': 'multipart/form-data' })
.field('user', u)
.field('hostnames', h.join(' '))
.end(response => {
console.log(response.body);
});
Cela pourrait ĂȘtre considĂ©rĂ© comme un doublon de #789.
J'ai pu utiliser le package form-data
avec Axios dans nodejs. Il fournit essentiellement une interface de type FormData
. Vous devez cependant faire attention Ă transmettre manuellement les en-tĂȘtes qu'il gĂ©nĂšre Ă Axios. Par exemple:
const axios = require('axios');
const FormData = require('form-data');
const form = new FormData();
// Second argument can take Buffer or Stream (lazily read during the request) too.
// Third argument is filename if you want to simulate a file upload. Otherwise omit.
form.append('field', 'a,b,c', 'blah.csv');
axios.post('http://example.org/endpoint', form, {
headers: form.getHeaders(),
}).then(result => {
// Handle resultâŠ
console.log(result.data);
});
Oui, j'ai essayé avec ce package form-data
. Eh bien, c'est bon maintenant, j'ai changé l'API cÎté serveur pour analyser JSON à la place.
quelqu'un peut-il s'il vous plaĂźt montrer ce qui doit ĂȘtre fait dans l'application nodejs ??
@ ar412 J'ai essayé de donner un exemple sur https://github.com/mzabriskie/axios/issues/1006#issuecomment -320165427, pourriez-vous clarifier ce que vous demandez ?
@binki si axios est utilisé pour envoyer une demande de publication à une restapi avec des données, alors comment récupérer ces données dans l'api de repos (qui se trouve dans une application express).
vous pouvez essayer ceci https://expressjs.com/en/4x/api.html#req @ar412
@ar412 Pour recevoir des données en plusieurs busboy
comme recommandé par body-parser
's docs . Fondamentalement, pour apprendre à gérer les fichiers téléchargés dans Express, ce n'est pas du tout lié à Axios, vous feriez donc mieux de demander ailleurs car vous avez détourné ce fil ;-). Par exemple, voir cette réponse sur SO .
Message d'erreur reçu : form.getHeaders() n'est pas une fonction
@binki
Hey! J'ai un serveur hapi.js dans lequel je veux POSTER un fichier image stocké dans une variable en utilisant fs.readFile(chemin).
Je ne parviens pas Ă le faire fonctionner en envoyant cela en tant que FormData()
C'est mon code :
fs.readFile(__dirname+'/../static/lisa_server.jpg', (error, imageData) => {
var form = new FormData()
form.append('file', imageData, {
filename: 'unicycle.jpg', // ... or:
filepath: '/../static/lisa_server.jpg',
contentType: 'image/jpg',
knownLength: 19806
})
Ensuite, j'envoie le formulaire comme corps de la demande et je définis les options['Content-Type'] = 'multipart/form-data'
Pourriez-vous aider?
TrÚs appréciée!
@bstolarz si vous passez un Buffer
, ce que vous faites, vous n'avez pas besoin de passer knownLength
. De plus, si vous lisez ce que vous avez écrit (euh, copié et collé à partir des exemples de README de filename
ou filepath
â pas les deux. Les seules choses qu'il pourrait ĂȘtre judicieux pour vous de dĂ©finir sont :
filename
OU filepath
contentType
(au cas oĂč le serveur requiert une valeur de type de contenu particuliĂšre, sinon cela peut probablement ĂȘtre omis).Ce que je parie, c'est que la taille de l'image que vous envoyez a une taille qui n'est pas 19806
parce que cette 19806
est quelque chose que vous avez copié à partir d'un exemple dans form-data
s » docs plutÎt que calculés pour vos propres données. Cela est susceptible de provoquer une erreur de form-data
ou d'Ă©crire des donnĂ©es invalides dans la requĂȘte HTTP. Avez-vous vĂ©rifiĂ© si le axios.post()
renvoyé Promise
est un rejet ou si une exception est levĂ©e ? Si la requĂȘte axios est rejetĂ©e, vĂ©rifiez si l'objet d'erreur a une clĂ© result
et, si c'est le cas, vérifiez quelle est la err.result.status
. S'il s'agit d'une valeur 4xx autre que 404 ou 403, cela signifie probablement que le serveur rejette une requĂȘte mal formĂ©e qui pourrait rĂ©sulter d'une taille connue incorrecte.
@binki
Hé, merci pour votre réponse. J'ai corrigé les choses que vous avez mentionnées, donc maintenant mon code est
fs.readFile(__dirname+'/../static/lisa_server.jpg', (error, imageData) => {
var form = new FormData()
form.append('file', imageData, {
filepath: __dirname+'/../static/lisa_server.jpg',
contentType: 'image/jpg'
})
Mais le serveur renvoie 411 "La longueur est requise" (j'ai Ă©galement essayĂ© fs.createReadStream qui semble ĂȘtre entiĂšrement pris en charge par FormData, mais j'obtiens la mĂȘme erreur de longueur).
@binki
J'ai rĂ©ussi Ă dĂ©finir la longueur du contenu de l'en-tĂȘte dans la couche la plus basse et je n'obtiens plus cette erreur.
Maintenant que je ne reçois pas de 411 du serveur, je suis revenu à l'erreur que j'avais une fois 400 - "Aucun fichier fourni".
Voici Ă quoi ressemble la demande
Demande de départ
{ adapter: [Function: httpAdapter],
transformRequest: { '0': [Function: transformRequest] },
transformResponse: { '0': [Function: transformResponse] },
timeout: 5000,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
validateStatus: [Function: validateStatus],
headers:
{ common: { Accept: 'application/json, text/plain, */*' },
delete: {},
get: {},
head: {},
post: { 'Content-Type': 'application/json' },
put: { 'Content-Type': 'application/json' },
patch: { 'Content-Type': 'application/json' },
'User-Agent': 'trojan server 1.0',
'X-Origin-Panamera': 'Staging',
'Content-Length': 25247 },
baseURL: 'https://letgoar-a.akamaihd.net/api/v1',
method: 'post',
url: 'https://<baseDomain>/api/v1/images',
data:
FormData {
_overheadLength: 218,
_valueLength: 25247,
_valuesToMeasure: [],
writable: false,
readable: true,
dataSize: 0,
maxDataSize: 2097152,
pauseStreams: true,
_released: false,
_streams:
[ '----------------------------677738213014296377492349\r\nContent-Disposition: form-data; name="file"; filename="/Users/brenda/repos/qreator2/qreator/trojan-server/src/static/lisa_server.jpg"\r\nContent-Type: image/jpg\r\n\r\n',
<Buffer ff d8 ff e0 00 10 4a 46 49 46 00 01 01 01 00 48 00 48 00 00 ff e2 11 2c 49 43 43 5f 50 52 4f 46 49 4c 45 00 01 01 00 00 11 1c 61 70 70 6c 02 00 00 00 ... >,
[Function: bound ] ],
_currentStream: null,
_boundary: '--------------------------677738213014296377492349' },
'Content-Type': 'multipart/form-data' }
J'espÚre que vous vérifiez cela. Pour vous, cela ressemble-t-il à une demande raisonnable ?
Merci d'avance
@bstolarz J'ai fait de mon mieux pour reproduire votre problÚme. Cependant, je ne peux pas. J'ai écrit ce code pour essayer d'imiter ce que vous faites. Cependant, j'ai volontairement omis de définir manuellement Content-Length
. Je suis convaincu que le fait que vous paramétriez Content-Length
pourrait ĂȘtre liĂ© Ă votre problĂšme. Veuillez essayer de laisser le form-data
s'occuper de calculer cela pour vousâc'est pourquoi vous devez appeler form.getHeaders()
.
Voir cette pĂąte : https://gist.github.com/binki/10ac3e91851b524546f8279733cdadad . Peut-ĂȘtre pouvez-vous modifier la façon dont vous appelez axios.post()
ou axios()
pour correspondre à mon exemple et cela fonctionnera pour vous ?
Si vous rencontrez toujours des problĂšmes, essayez de dĂ©placer votre code vers son propre script et de le reproduire lĂ -bas. Cela peut vous aider Ă rĂ©soudre le problĂšme. Si vous ĂȘtes toujours bloquĂ©, veuillez publier le code complet, y compris l'appel Ă axios()
ou axios.post()
en guise d'essentiel et le lier ici et, si je peux, je l'examinerai.
ça ne marche toujours pas du tout...
@rodrigogs Si vous voulez de l'aide, vous devrez ĂȘtre plus dĂ©taillĂ© ;-).
J'ai suivi cette recherche utile sur Axios et la solution finale fonctionne pour moi ( lien )
En voici le copier/coller :
import fs from 'fs';
import FormData from 'form-data';
import axios from 'axios';
let data = fs.createReadStream(__dirname + '/test.jpg');
let form = new FormData();
form.append('type','image');
form.append('media',data,'test.jpg');
function getHeaders(form) {
return Promise((resolve, reject) => {
form.getLength((err, length) => {
if(err) { reject(err); }
let headers = Object.assign({'Content-Length': length}, form.getHeaders());
resolve(headers);
});
});
}
getHeaders(form)
.then((headers) => {
return axios.post(url, form, {headers:headers})
})
.then((response)=>{
console.log(response.data)
})
.catch(e=>{console.log(e)})
@westofpluto , j'obtiens aussi la mĂȘme erreur. @binki , des idĂ©es ?
L'erreur
form.getHeaders n'est pas une fonction
@smplyjr Pouvez-vous donner plus de contexte et me dire comment vous obtenez form
? Sans code, nous ne pouvons pas dire ce que vous faites ou vous aider.
Pour les utilisateurs de nodejs, rĂ©solvez en utilisant la bibliothĂšque de chaĂźne de requĂȘte, comme suit :
const querystring = require('querystring')
axios
.post(URL, querystring.stringify(data))
.then((response) => ...)
.catch((error) => ...)
Comme @heldrida l'a mentionnĂ©, utilisez la chaĂźne de requĂȘte. C'est ainsi qu'axios recommande de procĂ©der ici : https://www.npmjs.com/package/axios#nodejs. Le package form-data
a toutes sortes de problĂšmes ici et vous finirez par vous arracher les cheveux en essayant de le faire fonctionner.
@heldrida @ashok-sc Comment dois-je utiliser querystring
ou qs
pour tĂ©lĂ©charger un fichier avec axios ? J'utilise axios pour tĂ©lĂ©charger des fichiers Ă partir d'un AWS Lambda et je n'ai Ă©videmment pas accĂšs Ă l'objet File Ă partir de lĂ
@bstolarz J'ai fait de mon mieux pour reproduire votre problÚme. Cependant, je ne peux pas. J'ai écrit ce code pour essayer d'imiter ce que vous faites. Cependant, j'ai volontairement omis de définir manuellement
Content-Length
. Je suis convaincu que le fait que vous paramétriezContent-Length
pourrait ĂȘtre liĂ© Ă votre problĂšme. Veuillez essayer de laisser leform-data
s'occuper de calculer cela pour vousâc'est pourquoi vous devez appelerform.getHeaders()
.Voir cette pĂąte : https://gist.github.com/binki/10ac3e91851b524546f8279733cdadad . Peut-ĂȘtre pouvez-vous modifier la façon dont vous appelez
axios.post()
ouaxios()
pour correspondre Ă mon exemple et cela fonctionnera pour vous ?Si vous rencontrez toujours des problĂšmes, essayez de dĂ©placer votre code vers son propre script et de le reproduire lĂ -bas. Cela peut vous aider Ă rĂ©soudre le problĂšme. Si vous ĂȘtes toujours bloquĂ©, veuillez publier le code complet, y compris l'appel Ă
axios()
ouaxios.post()
en guise d'essentiel et le lier ici et, si je peux, je l'examinerai.
Merci mec. L'ajout de Content-Length a résolu mon problÚme maintenant, je peux utiliser les appels axios backend-2-backend avec FormData :
const options = {
method: 'POST',
url: myUrl,
data: justJsonBody,
transformRequest: [function (data, headers) {
const formData = convertToFormData(data); // returrns ForrmData from form-data
headers['Content-Type'] = formData.getHeaders()['content-type'];
headers['Content-Length'] = formData._overheadLength;
return formData;
}]
};
Cela pourrait ĂȘtre considĂ©rĂ© comme un doublon de #789.
J'ai pu utiliser le package
form-data
avec Axios dans nodejs. Il fournit essentiellement une interface de typeFormData
. Vous devez cependant faire attention Ă transmettre manuellement les en-tĂȘtes qu'il gĂ©nĂšre Ă Axios. Par exemple:const axios = require('axios'); const FormData = require('form-data'); const form = new FormData(); // Second argument can take Buffer or Stream (lazily read during the request) too. // Third argument is filename if you want to simulate a file upload. Otherwise omit. form.append('field', 'a,b,c', 'blah.csv'); axios.post('http://example.org/endpoint', form, { headers: form.getHeaders(), }).then(result => { // Handle result⊠console.log(result.data); });
Une autre façon ici. De cette façon, vous pouvez ajouter un agent proxy à et à d'autres configurations :
const axios = require('axios');
const FormData = require('form-data');
const ProxyAgent = require('proxy-agent');
const form = new FormData();
// Second argument can take Buffer or Stream (lazily read during the request) too.
// Third argument is filename if you want to simulate a file upload. Otherwise omit.
form.append('field', 'a,b,c', 'blah.csv');
axios({
method: 'POST',
url: 'http://example.org/endpoint',
data: form,
agent: new ProxyAgent("https://username:[email protected]:8080"),
headers: bodyFormData.getHeaders()
}).then(result => {
// Handle resultâŠ
console.log(result.data);
});
Cela fonctionne pour moi.
// ES6
import axios from 'axios';
import FormData from 'form-data';
import fs from 'fs';
FormData.prototype.getHeadersWithContentLength = function getHeadersWithContentLength() {
return new Promise((resolve, reject) => {
this.getLength((err, length) =>
err ? reject(err) : resolve({ ...this.getHeaders(), 'Content-Length': length })
)
})
}
const payload = new FormData();
const form = new formidable.IncomingForm();
form.parse(req, (err, fields, { file }) => {
if (err) return;
payload.append("file", fs.createReadStream(file.path), {
filename: file.name,
contentType: file.type
});
payload.getHeadersWithContentLength().then(headers => {
api
.post(endpoint, payload, { headers })
.then(({ data }) => data)
.then(data => res.json({ data }));
});
});
Merci à tous les contributeurs de cet article. AprÚs avoir passé des heures à avoir des problÚmes pour publier mon formulaire form-data
aide d'Axios, sur un backend qui le publie dans un compartiment Amazon, la solution s'est avĂ©rĂ©e ĂȘtre de dĂ©finir manuellement content-length
....
Pour tous ceux qui ont des problĂšmes avec mon code, cela peut peut-ĂȘtre aider le prochain Ă avoir des problĂšmes pour que cela fonctionne :)
const axios = require('axios');
const FormData = require('form-data');
// Where buffer is a file
formData.append('file', buffer);
// Added a promise version like seen in earlier comments to get this
const contentLength = await formData.getLength();
await axios(`<ENDPOINT>`, {
method: 'POST',
baseURL: <BASE_URL>,
params: {
fileName: '<FILE_NAME>.png'
},
headers: {
authorization: `Bearer <TOKEN>`,
...formData.getHeaders(),
'content-length': contentLength
},
data: formData
});
AprÚs avoir passé des heures à avoir des problÚmes pour publier mon formulaire
form-data
aide d'Axios, sur un backend qui le publie dans un compartiment Amazon, la solution s'est avĂ©rĂ©e ĂȘtre de dĂ©finir manuellementcontent-length
....
Oui. Un de mes collĂšgues et moi avons Ă©galement passĂ© plusieurs heures Ă essayer de poster des fichiers sur un backend qui rĂ©pondrait qu'aucune donnĂ©e n'Ă©tait soumise, alors que c'Ă©tait Ă©videmment le cas, car nous pouvions suivre la demande et voir le contenu. Le problĂšme Ă©tait l'en-tĂȘte de longueur de contenu manquant.
A noter, si vous ajoutez un tampon au FormData, c'est bien si vous appelez formData.getLengthSync()
mais si vous avez affaire Ă un flux, vous devez d'abord stat le fichier avec fs.statSync(filePath).size
ou obtenir la taille complĂšte d'une autre maniĂšre (comme Ă partir d'un en-tĂȘte de longueur de contenu d'un amont), par exemple si le flux provient d'une requĂȘte ou d'un socket ou autre. Si votre flux provient du disque Ă la place, fs.statSync(filePath).size
donnera la taille en octets, vous pouvez donc l'ajouter dansknownLength lors de l'ajout à FormData :
formData.append("file", fs.createReadStream(filePath), { filename: 'whatever.pdf', knownLength: fs.statSync(filePath).size });
Bien sĂ»r, toutes les mĂ©thodes de synchronisation peuvent ĂȘtre remplacĂ©es par des mĂ©thodes asynchrones et le mot-clĂ© wait.
// Added a promise version like seen in earlier comments to get this const contentLength = formData.getLength();
Je suppose que vous avez oublié un await
avant formData en effet...
Commentaire le plus utile
Cela pourrait ĂȘtre considĂ©rĂ© comme un doublon de #789.
J'ai pu utiliser le package
form-data
avec Axios dans nodejs. Il fournit essentiellement une interface de typeFormData
. Vous devez cependant faire attention Ă transmettre manuellement les en-tĂȘtes qu'il gĂ©nĂšre Ă Axios. Par exemple: