2016-03-04 24 views
7

Sto cercando di utilizzare API di recupero per caricare file su un server node.js (sto usando il pollyfill di Github se ha qualcosa a che fare con questo: https://github.com/github/fetch).Errore recupero API e multer durante il caricamento del file

La richiesta viene fatta in questo modo:

const data = new FormData(); 
data.append('file', file); 
return fetch(this.concatToUrl(url), { 
    method: 'post', 
    headers: Object.assign({}, this.getHeaders(), {'Content-Type': 'multipart/form-data'}), 
    body: data, 
}); 

Sul lato server che ho, questa dichiarazione di percorso:

app.post('/media', upload.single('file'), mediaRoutes.postMedia); 

e cercando di ottenere il file in questo modo:

exports.postMedia = function(req, res) { 
    console.log('req.file', req.file, req.files, req.body); 
    return res.sendStatus(200); 
} 

Ma il req.file non viene compilato.

Anche io sto ottenendo questo errore da parte espresso:

Error: Multipart: Boundary not found 
[2]  at new Multipart (/Users/jmanzano/Development/web/test/node_modules/busboy/lib/types/multipart.js:58:11) 
[2]  at Multipart (/Users/jmanzano/Development/web/test/node_modules/busboy/lib/types/multipart.js:26:12) 
[2]  at Busboy.parseHeaders (/Users/jmanzano/Development/web/test/node_modules/busboy/lib/main.js:64:22) 
[2]  at new Busboy (/Users/jmanzano/Development/web/test/node_modules/busboy/lib/main.js:21:10) 
[2]  at multerMiddleware (/Users/jmanzano/Development/web/test/node_modules/multer/lib/make-middleware.js:32:16) 
[2]  at Layer.handle [as handle_request] (/Users/jmanzano/Development/web/test/node_modules/express/lib/router/layer.js:95:5) 
[2]  at next (/Users/jmanzano/Development/web/test/node_modules/express/lib/router/route.js:131:13) 
[2]  at Route.dispatch (/Users/jmanzano/Development/web/test/node_modules/express/lib/router/route.js:112:3) 
[2]  at Layer.handle [as handle_request] (/Users/jmanzano/Development/web/test/node_modules/express/lib/router/layer.js:95:5) 
[2]  at /Users/jmanzano/Development/web/test/node_modules/express/lib/router/index.js:277:22 
[2]  at Function.process_params (/Users/jmanzano/Development/web/test/node_modules/express/lib/router/index.js:330:12) 
[2]  at next (/Users/jmanzano/Development/web/test/node_modules/express/lib/router/index.js:271:10) 
[2]  at cors (/Users/jmanzano/Development/web/test/node_modules/cors/lib/index.js:178:7) 
[2]  at /Users/jmanzano/Development/web/test/node_modules/cors/lib/index.js:228:17 
[2]  at originCallback (/Users/jmanzano/Development/web/test/node_modules/cors/lib/index.js:217:15) 
[2]  at /Users/jmanzano/Development/web/test/node_modules/cors/lib/index.js:222:13 
[2]  at optionsCallback (/Users/jmanzano/Development/web/test/node_modules/cors/lib/index.js:203:9) 
[2]  at /Users/jmanzano/Development/web/test/node_modules/cors/lib/index.js:208:7 
[2]  at Layer.handle [as handle_request] (/Users/jmanzano/Development/web/test/node_modules/express/lib/router/layer.js:95:5) 
[2]  at trim_prefix (/Users/jmanzano/Development/web/test/node_modules/express/lib/router/index.js:312:13) 
[2]  at /Users/jmanzano/Development/web/test/node_modules/express/lib/router/index.js:280:7 
[2]  at Function.process_params (/Users/jmanzano/Development/web/test/node_modules/express/lib/router/index.js:330:12) 

e questa è la configurazione tramite middleware:

app.use(bodyParser.urlencoded({extended: true})); 
app.use(bodyParser.json()); 
app.use(expressValidator()); 
app.use(logger('dev')); 
app.use(cookieParser()); 
app.use(methodOverride()); 
app.use(passport.initialize()); 
app.use(passport.session()); 
app.set('JWTSuperSecret', jwtConfig.secret); 

if (process.env.NODE_ENV !== 'production') { 
    app.use(cors()); 
} 

Inoltre, questo è correttamente lavorando con postino. Quindi, penso di fare qualcosa di sbagliato con la richiesta.

Grazie!

risposta

3

Non è necessario assegnare un'intestazione {Content-Type': 'multipart/form-data'}: il browser sostituisce il proprio.

Ma se si espone, allora non è specificato boundary dopo content-type:multipart/form-data; boundary=... in Request Headers prima Request Payload e che sta causando l'errore sul lato server.

Se si apre la console del browser e si vedono le intestazioni, verrà visualizzato.

Quindi, basta:

fetch(this.concatToUrl(url), { 
    method: 'post', 
    body: data, 
}); 

Oppure, se avete bisogno di intestazioni personalizzate è possibile aggiungerli in questo modo:

var headers = Object.assign({}, 
          {'content-type': 'application/json'}, 
          this.getHeaders(), 
          {'Content-Type': 'multipart/form-data'} 
); 

    // Removal should be case insensitive, or in any case, the header will be included: 


Object.keys(headers) 
     .forEach(function(k) { 
     if (k.toLowerCase()==='content-type') delete headers[k] 
     }) 

const data = new FormData(); 
data.append('file', file); 
return fetch(this.concatToUrl(url), { 
    method: 'post', 
    headers: headers, 
    body: data, 
}); 
+0

Il problema con questo approccio è che devo impostare più intestazioni personalizzate (per consentire l'autenticazione JWT per esempio). Come posso ottenerlo? –

+1

Solo proprietà 'content-type' dalla lista delle intestazioni. Vedi l'aggiornamento. –

8

Per coloro inciampo su questo post che hanno l'errore quando si utilizza postino accertarsi di non specificare il tipo di contenuto nelle intestazioni.

+0

oh mio dio, grazie –