我試圖從移動應用程序上載圖像文件(這是寫在原生態,現在在iOS上運行)。NodeJS/Restify:如何在API中接收文件上傳?
該文件發送到我的REST API,如下所示。我有兩個問題,這:
- 我不明白
req.body
,因爲它始終是一個空的對象,雖然頭部被正確提交。 - 我想通過
gridfs-stream
將接收到的文件寫入我的數據庫(GridFS),但我不明白在哪裏放置該代碼。
API
const restify = require('restify')
const winston = require('winston')
const bunyanWinston = require('bunyan-winston-adapter')
const mongoose = require('mongoose')
const Grid = require('gridfs-stream')
const config = require('../config')
// Configure mongoose to work with javascript promises
mongoose.Promise = global.Promise
// Setting up server
const server = restify.createServer({
name: config.name,
version: config.version,
log: bunyanWinston.createAdapter(log)
})
server.use(restify.plugins.multipartBodyParser())
server.listen(config.port,() => {
mongoose.connection.on('open', (err) => {
server.post('/upload', (req, res, next) => {
console.log(req.headers) // <- returns headers as expected
/* Problem 1 */
console.log(req.body) // <- is empty object (unexpected)
res.send(200, { message: 'successful upload' })
res.end()
})
})
global.db = mongoose.connect(config.db.uri, { useMongoClient: true })
/* Problem 2: The recieved file should be stored to DB via `gridfs-stream` */
// I think this is the wrong place for this line...
var gfs = Grid(global.db, mongoose.mongo)
})
我試圖找到的錯誤,但我沒有找到它,所以這裏的數據,這是我得到我的API:
頭
{
host: 'localhost:3000',
'content-type': 'multipart/form-data; boundary=pUqK6oKvY65OfhaQ3h01xWg0j4ajlanAA_e3MXVSna4F8kbg-zT0V3-PeJQm1QZ2ymcmUM',
'user-agent': 'User/1 CFNetwork/808.2.16 Darwin/15.6.0',
connection: 'keep-alive',
accept: '*/*',
'accept-language': 'en-us',
'accept-encoding': 'gzip, deflate',
'content-length': '315196'
}
身體
{ }
爲什麼body
爲空?
陣營本地文件上傳
這是我如何將文件發送到API。我還告訴你一些變量的內容:
async function upload (photo) {
console.log('photo', photo); // OUTPUT SHOWN BELOW
if (photo.uri) {
// Create the form data object
var data = new FormData()
data.append('picture', { uri: photo.uri, name: 'selfie.jpg', type: 'image/jpg' })
// Create the config object for the POST
const config = {
method: 'POST',
headers: {
'Accept': 'application/json'
},
body: data
}
console.log('config', config); // OUTPUT SHOWN BELOW
fetchProgress('http://localhost:3000/upload', {
method: 'post',
body: data
}, (progressEvent) => {
const progress = progressEvent.loaded/progressEvent.total
console.log(progress)
}).then((res) => console.log(res), (err) => console.log(err))
}
}
const fetchProgress = (url, opts = {}, onProgress) => {
console.log(url, opts)
return new Promise((resolve, reject) => {
var xhr = new XMLHttpRequest()
xhr.open(opts.method || 'get', url)
for (var k in opts.headers || {}) {
xhr.setRequestHeader(k, opts.headers[k])
}
xhr.onload = e => resolve(e.target)
xhr.onerror = reject
if (xhr.upload && onProgress) {
xhr.upload.onprogress = onProgress // event.loaded/event.total * 100 ; //event.lengthComputable
}
xhr.send(opts.body)
})
}
照片
{
fileSize: 314945,
origURL: 'assets-library://asset/asset.JPG?id=106E99A1-4F6A-45A2-B320-B0AD4A8E8473&ext=JPG',
longitude: -122.80317833333334,
fileName: 'IMG_0001.JPG',
height: 2848,
width: 4288,
latitude: 38.0374445,
timestamp: '2011-03-13T00:17:25Z',
isVertical: false,
uri: 'file:///Users/User/Library/Developer/CoreSimulator/Devices/D3FEFFA8-7446-42AB-BC7E-B6EB88DDA840/data/Containers/Data/Application/17CE8C0A-B781-4E56-9347-857E74055119/Documents/images/69C2F27F-9EEE-4611-853E-FC7FF6E5C373.jpg'
}
配置
'http://localhost:3000/upload',
{
method: 'post',
body:
{
_parts:
[
[ 'picture',
{ uri: 'file:///Users/User/Library/Developer/CoreSimulator/Devices/D3FEFFA8-7446-42AB-BC7E-B6EB88DDA840/data/Containers/Data/Application/17CE8C0A-B781-4E56-9347-857E74055119/Documents/images/69C2F27F-9EEE-4611-853E-FC7FF6E5C373.jpg',
name: 'selfie.jpg',
type: 'image/jpg' }
]
]
}
}
我覺得data
(應該在config
被髮送的體)格式不正確。爲什麼數組中有一個數組?
不是一個直接的答案,但我認爲純JavaScript會少一些高性能的,所以我建議使用反應原生取二進制大對象,其中有上傳進度反饋也。 – eden
@Eden:也許你可以發佈一些代碼,上面的代碼應該如何與react-native-fetch-blob一起完成......? – user3142695
當然,給我幾分鐘。 – eden