React-Native移动端PDF上传NodeJS API问题求助
Hey there, let's tackle this PDF upload problem you've been stuck on for a week! That SyntaxError you're seeing is the key clue here—let's break it down and fix it step by step.
What's Causing the Error?
The error SyntaxError: Unexpected token # in JSON at position 0 happens because your Express server is probably configured with body-parser.json() to auto-parse JSON request bodies. But when you upload files via Postman (or React Native), you're sending a multipart/form-data request, not JSON. The body-parser middleware tries to parse this non-JSON content as JSON, which fails spectacularly.
On top of that, your multer configuration has a small bug: .array("test", 0) sets the maximum number of allowed files to 0—so it's actually blocking any file uploads entirely!
Step-by-Step Fixes
1. Correct Your Multer Configuration
First, fix the multer setup to allow file uploads. If you're only uploading one PDF at a time, use .single("test") instead of .array() (or set the max count to 1 if you want to use array):
const multer = require('multer') const fs = require('fs'); // Ensure uploads folder exists (prevents "no such file or directory" errors) const uploadDir = "./uploads"; if (!fs.existsSync(uploadDir)) { fs.mkdirSync(uploadDir); } var Storage = multer.diskStorage({ destination: (req, file, callback) => { callback(null, uploadDir); }, filename: (req, file, callback) => { callback(null, `${file.fieldname}_${Date.now()}_${file.originalname}`); } }); // Use .single("test") for single file upload, or .array("test", 1) if you need multiple var upload = multer({ storage: Storage }).single("test");
2. Adjust Express Middleware Order
Make sure your body-parser.json() middleware is applied globally, but that multer handles the file upload route specifically. Body-parser won't interfere with multer's handling of multipart/form-data requests as long as multer is used for those routes.
Here's how your main Express server file should look:
const express = require('express'); const bodyParser = require('body-parser'); const jwt = require('jsonwebtoken'); const app = express(); // Parse JSON for regular API requests (this is fine) app.use(bodyParser.json()); // Import your multer setup and route handler const quotationRoutes = require('./your-route-file.js'); app.post('/add-quotation', quotationRoutes.add_quotation); app.listen(3000, () => console.log('Server running on port 3000'));
3. Fix Your Route Handler
Update your add_quotation function to properly validate the JWT (use jwt.verify instead of just decode to ensure the token is valid) and handle errors better:
const jwt = require('jsonwebtoken'); // Make sure you have your JWT secret defined const JWT_SECRET = 'your-secret-key-here'; module.exports = { add_quotation: (req, res) => { let token = req.get('x-access-token') // Verify token validity instead of just decoding jwt.verify(token, JWT_SECRET, (err, decoded) => { if (err) { return res.status(401).send("Invalid or expired token"); } upload(req, res, (err) => { if (err) { console.error("Upload error:", err); return res.status(500).send("Something went wrong during upload!"); } return res.send("File uploaded successfully!"); }); }); } }
4. Test with Postman Correctly
When testing in Postman:
- Select the POST method and enter your API endpoint URL
- Go to the Body tab, select
form-data - Add a key named
test(must match the field name in multer), set the type to File, then select your PDF - Do NOT manually set the
Content-Typeheader toapplication/json—Postman will auto-set the correctmultipart/form-dataheader for you
Bonus: React Native Upload Tips
When you move to React Native, use FormData to construct the request:
import { Platform } from 'react-native'; const uploadPDF = async (pdfUri) => { const formData = new FormData(); // For iOS, you might need to adjust the uri format const fileUri = Platform.OS === 'ios' ? pdfUri.replace('file://', '') : pdfUri; formData.append('test', { uri: fileUri, name: 'document.pdf', type: 'application/pdf' }); try { const response = await fetch('http://your-server-url/add-quotation', { method: 'POST', headers: { 'x-access-token': 'your-jwt-token-here', // Don't set Content-Type manually—fetch will handle it }, body: formData }); const result = await response.text(); console.log(result); } catch (err) { console.error(err); } };
内容的提问来源于stack exchange,提问作者Lucatorze

