
A Node.js module for parsing form data, especially file uploads.
[![Code style][codestyle-img]][codestyle-url] [![codecoverage][codecov-img]][codecov-url] [![linux build status][linux-build-img]][build-url] [![macos build status][macos-build-img]][build-url]
Se você tiver qualquer tipo de pergunta sobre como fazer, por favor leia o [Contributing Guia][contributing-url] e [Código de Conduta][code_of_conduct-url] documentos.
Para relatórios de bugs e solicitações de recursos, [crie uma issue][open-issue-url] ou ping @tunnckoCore / @3a1FcBx0 no Twitter.
[![Conventional Commits][ccommits-img]][ccommits-url] [![Minimum Required Nodejs][nodejs-img]][npmv-url] [![Tidelift Subscription][tidelift-img]][tidelift-url] [![Buy me a Kofi][kofi-img]][kofi-url] [![Renovate App Status][renovateapp-img]][renovateapp-url] [![Make A Pull Request][prs-welcome-img]][prs-welcome-url]
Este projeto é semanticamente versionado e está disponível como parte da [Assinatura Tidelift][tidelift-url] para nível profissional garantias, suporte aprimorado e segurança. Saiba mais.
Os mantenedores do formidable e milhares de outros pacotes estão trabalhando
com Tidelift para fornecer suporte comercial e manutenção para o Open Source
dependências que você usa para construir seus aplicativos. Economize tempo, reduza riscos e
melhorar a integridade do código, enquanto paga aos mantenedores das dependências exatas que você
usar.
[![][npm-weekly-img]][npmv-url] [![][npm-monthly-img]][npmv-url] [![][npm-yearly-img]][npmv-url] [![][npm-alltime-img]][npmv-url]
Verifique VERSION NOTES para obter mais informações sobre os planos v1, v2 e v3, NPM dist-tags e branches.
Este módulo foi inicialmente desenvolvido por @felixge para Transloadit, um serviço focado em upload e codificação de imagens e vídeos. Foi testado em batalha contra centenas de GBs de uploads de arquivos de uma grande variedade de clientes e é considerado pronto para produção e é usado na produção por anos.
Atualmente, somos poucos mantenedores tentando lidar com isso. :) Mais contribuidores são sempre bem-vindos! ❤️ Pule issue #412 que está fechado, mas se você estiver interessado, podemos discuti-lo e adicioná-lo após regras estritas, como ativar o Two-Factor Auth em suas contas npm e GitHub.
options.fileWriteStreamHandler)Este projeto requer Node.js >= 10.13. Instale-o usando
yarn ou npm.
Nós altamente recomendamos usar o Yarn quando pensar em contribuir para este projeto.
Este é um pacote de baixo nível e, se você estiver usando uma estrutura de alto nível, pode já estar incluído. Verifique os exemplos abaixo e a pasta examples/.
# v2
npm install formidable
npm install formidable@v2
# v3
npm install formidable@v3
Nota: Em um futuro próximo, a v3 será publicada na dist-tag latest do NPM.
Versões futuras não prontas serão publicadas nas dist-tags *-next para a versão correspondente.
Para mais exemplos veja o diretório examples/.
Analisar um upload de arquivo de entrada, com o
Módulo http integrado do Node.js.
import http from 'node:http';
import formidable, {errors as formidableErrors} from 'formidable';
const server = http.createServer((req, res) => {
if (req.url === '/api/upload' && req.method.toLowerCase() === 'post') {
// analisar um upload de arquivo
const form = formidable({});
form.parse(req, (err, fields, files) => {
if (err) {
// exemplo para verificar um erro muito específico
if (err.code === formidableErrors.maxFieldsExceeded) {
}
res.writeHead(err.httpCode || 400, { 'Content-Type': 'text/plain' });
res.end(String(err));
return;
}
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ fields, files }, null, 2));
});
return;
}
// mostrar um formulário de upload de arquivo
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(`
<h2>With Node.js <code>"http"</code> module</h2>
<form action="/api/upload" enctype="multipart/form-data" method="post">
Text field title: <input type="text" name="title" />
File: <input type="file" name="multipleFiles" multiple="multiple" />
<input type="submit" value="Upload" />
</form>
`);
});
server.listen(8080, () => {
console.log('Server listening on http://localhost:8080/ ...');
});
Existem várias variantes para fazer isso, mas o Formidable só precisa do Node.js Request stream, então algo como o exemplo a seguir deve funcionar bem, sem nenhum middleware Express.js de terceiros.
Ou tente o examples/with-express.js
import express from 'express';
import formidable from 'formidable';
const app = express();
app.get('/', (req, res) => {
res.send(`
<h2>With <code>"express"</code> npm package</h2>
<form action="/api/upload" enctype="multipart/form-data" method="post">
Text field title: <input type="text" name="title" />
File: <input type="file" name="someExpressFiles" multiple="multiple" />
<input type="submit" value="Upload" />
</form>
`);
});
app.post('/api/upload', (req, res, next) => {
const form = formidable({});
form.parse(req, (err, fields, files) => {
if (err) {
next(err);
return;
}
res.json({ fields, files });
});
});
app.listen(3000, () => {
console.log('Server listening on http://localhost:3000 ...');
});
Claro, com Koa v1, v2 ou future v3 as coisas
sao muito parecidas. Você pode usar formidable manualmente como mostrado abaixo ou através
do pacote koa-better-body que é
usando formidable sob o capô e suporte a mais recursos e diferentes
corpos de solicitação, verifique sua documentação para mais informações.
Nota: este exemplo está assumindo Koa v2. Esteja ciente de que você deve passar ctx.req
que é a solicitação do Node.js e NÃO o ctx.request que é a solicitação do Koa
objeto - há uma diferença.
import Koa from 'Koa';
import formidable from 'formidable';
const app = new Koa();
app.on('error', (err) => {
console.error('server error', err);
});
app.use(async (ctx, next) => {
if (ctx.url === '/api/upload' && ctx.method.toLowerCase() === 'post') {
const form = formidable({});
// não muito elegante, mas é por enquanto se você não quiser usar `koa-better-body`
// ou outros middlewares.
await new Promise((resolve, reject) => {
form.parse(ctx.req, (err, fields, files) => {
if (err) {
reject(err);
return;
}
ctx.set('Content-Type', 'application/json');
ctx.status = 200;
ctx.state = { fields, files };
ctx.body = JSON.stringify(ctx.state, null, 2);
resolve();
});
});
await next();
return;
}
// mostrar um formulário de upload de arquivo
ctx.set('Content-Type', 'text/html');
ctx.status = 200;
ctx.body = `
<h2>With <code>"koa"</code> npm package</h2>
<form action="/api/upload" enctype="multipart/form-data" method="post">
Text field title: <input type="text" name="title" />
File: <input type="file" name="koaFiles" multiple="multiple" />
<input type="submit" value="Upload" />
</form>
`;
});
app.use((ctx) => {
console.log('The next middleware is called');
console.log('Results:', ctx.state);
});
app.listen(3000, () => {
console.log('Server listening on http://localhost:3000 ...');
});
O benchmark é bastante antigo, da antiga base de código. Mas talvez seja bem verdade. Anteriormente, os números giravam em torno de ~ 500 mb/s. Atualmente com a mudança para o novo Node.js Streams API, é mais rápido. Você pode ver claramente as diferenças entre as versões do Node.
Observação: um benchmarking muito melhor pode e deve ser feito no futuro.
Benchmark realizado em 8 GB de RAM, Xeon X3440 (2,53 GHz, 4 núcleos, 8 threads)
~/github/node-formidable master
❯ nve --parallel 8 10 12 13 node benchmark/bench-multipart-parser.js
⬢ Node 8
1261.08 mb/sec
⬢ Node 10
1113.04 mb/sec
⬢ Node 12
2107.00 mb/sec
⬢ Node 13
2566.42 mb/sec

Todos os mostrados são equivalentes.
Por favor, passe options para a função/construtor, não atribuindo
eles para a instância form
import formidable from 'formidable';
const form = formidable(options);
Veja seus padrões em src/Formidable.js DEFAULT_OPTIONS
(a constante DEFAULT_OPTIONS).
options.encoding {string} - padrão 'utf-8'; define a codificação para campos de formulário de entrada,options.uploadDir {string} - padrão os.tmpdir(); o diretório para colocar os uploads de arquivos. Você pode movê-los mais tarde usando fs.rename().options.keepExtensions {boolean} - padrão false; incluir as extensões dos arquivos originais ou nãooptions.allowEmptyFiles {boolean} - padrão false; permitir upload de arquivos vaziosoptions.minFileSize {number} - padrão 1 (1byte); o tamanho mínimo do arquivo carregado.options.maxFiles {number} - padrão Infinity;
limitar a quantidade de arquivos carregados, defina Infinity para ilimitadooptions.maxFileSize {number} - padrão 200 * 1024 * 1024 (200mb);
limitar o tamanho de cada arquivo carregado.options.maxTotalFileSize {number} - padrão options.maxFileSize;
limitar o tamanho do lote de arquivos carregados.options.maxFields {number} - padrão 1000; limite o número de campos, defina Infinity para ilimitadooptions.maxFieldsSize {number} - padrão 20 * 1024 * 1024 (20mb);
limitar a quantidade de memória que todos os campos juntos (exceto arquivos) podem alocar em
bytes.options.hashAlgorithm {string | false} - padrão false; incluir checksums calculados
para arquivos recebidos, defina isso para algum algoritmo de hash, consulte
crypto.createHash
para algoritmos disponíveisoptions.fileWriteStreamHandler {function} - padrão null, que por padrão grava no sistema de arquivos da máquina host cada arquivo analisado; A função
deve retornar uma instância de um
fluxo gravável
que receberá os dados do arquivo carregado. Com esta opção, você pode ter qualquer
comportamento personalizado em relação a onde os dados do arquivo carregado serão transmitidos.
Se você deseja gravar o arquivo carregado em outros tipos de armazenamento em nuvem
(AWS S3, armazenamento de blob do Azure, armazenamento em nuvem do Google) ou armazenamento de arquivo privado,
esta é a opção que você está procurando. Quando esta opção é definida, o comportamento padrão de gravar o arquivo no sistema de arquivos da máquina host é perdido.options.filename {function} - padrão undefined Use-o para controlar newFilename. Deve retornar uma string. Será associado a options.uploadDir.
options.filter {function} - função padrão que sempre retorna verdadeiro.
Use-o para filtrar arquivos antes de serem carregados. Deve retornar um booleano.
options.filename {function} function (name, ext, part, form) -> stringonde a parte pode ser decomposta como
const { originalFilename, mimetype} = part;
Observação: Se este tamanho de campos combinados, ou tamanho de algum arquivo for excedido, um
O evento 'error' é disparado.
// A quantidade de bytes recebidos para este formulário até agora.
form.bytesReceived;
// O número esperado de bytes neste formulário.
form.bytesExpected;
options.filter {function} function ({name, originalFilename, mimetype}) -> booleanObservação: use uma variável externa para cancelar todos os uploads no primeiro erro
const options = {
filter: function ({name, originalFilename, mimetype}) {
// manter apenas imagens
return mimetype && mimetype.includes("image");
}
};
Analisa uma request do Node.js recebida contendo dados de formulário. Se callback for
fornecido, todos os campos e arquivos são coletados e passados para o retorno de chamada.
```js const form = formidable({ uploadDir: __dirname });
fo
$ claude mcp add formidable \
-- python -m otcore.mcp_server <graph>