test - Cómo publicar multipart/form-data con node.js superagent
supertest tutorial (4)
Estoy tratando de enviar el tipo de contenido en mi solicitud de publicación del superagente a multipart / form-data.
var myagent = superagent.agent();
myagent
.post(''http://localhost/endpoint'')
.set(''api_key'', apikey)
.set(''Content-Type'', ''multipart/form-data'')
.send(fields)
.end(function(error, response){
if(error) {
console.log("Error: " + error);
}
});
El error que recibo es: TypeError: Argumento debe ser una cadena
Si quito el:
.set(''Content-Type'', ''multipart/form-data'')
No recibo ningún error, pero mi back-end está recibiendo la solicitud como tipo de contenido: application / json
¿Cómo puedo forzar que el tipo de contenido sea multipart / form-data para poder acceder a req.files ()?
En 2017 , hazlo de esta manera.
En primer lugar, NO menciona ninguno de los siguientes:
.set(''Content-Type'', ''multipart/form-data'')
O
.type(''form'')
En segundo lugar, NO utiliza el .send
, utiliza .field(name, value)
.
Un ejemplo
Supongamos que desea enviar una solicitud de datos de formulario con lo siguiente:
- Dos campos de texto:
name
yphone
- un archivo:
photo
Entonces tu petición será algo como esto:
superagent
.post( ''https://example.com/api/foo.bar'' )
.set(''Authorization'', ''...'')
.accept(''application/json'')
.field(''name'', ''My name'')
.field(''phone'', ''My phone'')
.attach(''photo'', ''path/to/photo.gif'')
.then((result) => {
// process the result here
})
.catch((err) => {
throw err;
});
Y, digamos que desea enviar JSON como valor de uno de sus campos, entonces haría esto.
superagent
.post( ''https://example.com/api/dog.crow'' )
.accept(''application/json'')
.field(''data'', JSON.stringify({ name: ''value'' }) )
.then( ... )
.catch( ... )
Esto es lo que funcionó para mí. Tenía un formulario de campo único, que estaba cargando un archivo. Convertí el formulario en un elemento HTML5 FormData y luego lo hice de la siguiente manera:
var frm = new FormData(document.getElementById(''formId''));
var url = ''url/here'';
superagent.post(url)
.attach(''fieldInFormName'', frm.get(''fieldInFormName''))
.end( function (error, response) {
//handle response
});
Tenga en cuenta que probé varias formas de configurar ''Tipo de contenido'' manualmente en superagente, y nunca funcionó correctamente debido al identificador de varias partes necesario en el Tipo de contenido.
No está claro qué hay en la variable de fields
que está enviando, pero aquí hay algo de información que puede ayudarlo a determinar dónde está su problema.
Para empezar, si realmente está intentando crear una solicitud de varias partes, esta es la documentación oficial para hacerlo: docs
En cuanto al error que tienes ...
El motivo es que durante el proceso de preparación de la solicitud, SuperAgent comprueba los datos que se enviarán para ver si se trata de una cadena. Si no lo es, intenta serializar los datos según el valor del ''Tipo de contenido'', como se ve a continuación:
exports.serialize = {
''application/x-www-form-urlencoded'': qs.stringify,
''application/json'': JSON.stringify
};
que se usa aquí:
// body
if (''HEAD'' != method && !req._headerSent) {
// serialize stuff
if (''string'' != typeof data) {
var serialize = exports.serialize[req.getHeader(''Content-Type'')];
if (serialize) data = serialize(data);
}
// content-length
if (data && !req.getHeader(''Content-Length'')) {
this.set(''Content-Length'', Buffer.byteLength(data));
}
}
esto significa que para establecer un formulario ''Content-Type'' manualmente utilizarías
.set(''Content-Type'', ''application/x-www-form-urlencoded'')
o
.type(''form'')
como se mencionó risyasin
cualquier otro ''tipo de contenido'' no se serializará, y Buffer.byteLength(data)
lanzará posteriormente el Buffer.byteLength(data)
TypeError: Argument must be a string
excepción de TypeError: Argument must be a string
si el valor de su variable de fields
no es una cadena.
Pruebe .type(''form'')
lugar de .set(''Content-Type'', ''multipart/form-data'')
Consulte http://visionmedia.github.io/superagent/#setting-the-content-type