我正在尝试在我的项目中使用相机插件和文件传输。它们在 android 上运行良好,但当我在 ios 模拟器上测试时,当我尝试使用 cordova 文件传输插件上传照片时,我在服务器上收到一个空请求正文。
在下面的代码中,photo_url
是我从相机插件获得的响应。这包含我从图库中选择的照片的完整路径。这是我使用 console.log
时得到的值:
file:///Users/user/Library/Developer/CoreSimulator/Devices/87045654-FB0C-40E8-97A8-5634FC2D05E7/data/Containers/Data/Application/E0810976-FF0F-43E2-BC15-3EFDD93D61C4/tmp/cdv_photo_010.jpg
代码如下:
var options = new FileUploadOptions();
options.fileKey = 'file';
options.fileName = photo_url.substr(photo_url.lastIndexOf('/') + 1).split('?')[0];
options.mimeType = 'image/jpeg';
options.params = params;
var ft = new FileTransfer();
ft.upload(
photo_url, me.upload_url + path + '/photo/upload',
function(result){
console.log('success');
console.log(result);
},
function(err){
console.log('error');
console.log(err);
},
options
);
options.fileName
的值为:cdv_photo_010.jpg
。
我尝试寻找解决方案并找到了以下内容:
options.headers = {
Connection: "close"
};
options.chunkedMode = false;
我将它应用到我现有的代码中,但它仍然不起作用。我在服务器中获取的请求正文仍然是一个空对象。
我正在使用一个快速服务器和 multer 来处理文件上传。
这是服务器上的代码:
var multer_options = {
dest: './public/uploads',
fileSize: '',
fields: 10,
files: 1,
rename: function(fieldname, filename){
return random.string(30) + '-' + Date.now();
},
changeDest: function(original_dest, req, res){
console.log('org dest:');
console.log(original_dest);
console.log('request body: ');
console.log(req.body);
var j = JSON.parse(req.body);
console.log('parsed body: ');
console.log(j);
var request_data = req.body.request_data;
console.log('request data: ');
console.log(request_data);
var dest = original_dest + '/' + request_data.upload_path;
console.log('upload path: ');
console.log(request_data.upload_path);
console.log('dest: ');
console.log(dest);
var stat = null;
try{
stat = fs.statSync(dest);
}catch(err){
fs.mkdirSync(dest);
}
if(stat && !stat.isDirectory()){
throw new Error('Directory cannot be created because an inode of a different type exists at "' + dest + '"');
}
return dest;
}
};
Multer 已经处理了文件上传,所以我要做的就是编写指示 multer 更改目标目录的代码,这就是我上面的内容。在android中上传文件时,它工作正常。我获得请求正文的值。但在 ios 上它是空的。所以我认为问题要么出在 ios 模拟器上,要么是文件传输插件在使用 ios 模拟器时出现问题。
有什么想法吗?
最佳答案
文件上传:Cordova 文件传输插件 + ExpressJs Multer
下面的解决方案让我用 iPhone 相机拍照,然后将照片上传到 NodeJS 服务器。
@Kyokasuigetsu - Cordova 的文件传输插件几乎也放弃了 FILE_URI!
Notice that
options.fileKey = 'myPhoto'
andupload.single('myPhoto')
should have the same value. It refers to the field name for the file upload form.<!-- Upload a single file --> <form> <input type="file" name="myPhoto" /> </form>
安装所需的插件和模块(从控制台)
> cordova 插件添加 cordova-plugin-file-transfer;
> npm install express multer --save;
Cordova (native_app.js)
function uploadPhoto(fileUri) {
// file:///var/mobile/Containers/Data/Application/
// .../tmp/cdv_photo.jpg
console.log("fileUri:", fileUri);
var options, request;
options = new FileUploadOptions();
// The name 'fileKey' is confusing; it should be 'fieldname'
options.fileKey = 'myPhoto';
// fileName: 'cdv_photo.jpg';
options.fileName =
fileUri.substr(fileUri.lastIndexOf('/') + 1);
request = new FileTransfer();
request.upload(
fileUri,
encodeURI('http://localhost:8080/photos'),
function success(response) {
console.log("Success: Photo uploaded to server!");
},
function error(response) {
console.log("Error: Photo not uploaded to server!");
},
options
);
}
function capturePhoto(callback) {
navigator.camera.getPicture(
function success(fileUri) {
callback(fileUri);
},
function error() {},
{ // camera options
destinationType: Camera.DestinationType.FILE_URI,
sourceType: Camera.PictureSourceType.CAMERA,
encodingType: Camera.EncodingType.JPEG,
mediaType: Camera.MediaType.PICTURE
}
);
}
function captureAndUploadPhoto() {
capturePhoto(function (fileUrl) {
uploadPhoto(fileUrl);
});
}
document.addEventListener("deviceready", captureAndUploadPhoto, false);
NodeJs/ExpressJs (server_app.js)
var express, application, multer, upload;
express = require('express');
application = express();
multer = require('multer');
upload = multer({dest: 'uploads/'}).single('myPhoto');
application.get('/photos', upload, function (request, response) {
console.log(response.file);
response.status(204).end();
});
application.listen(8080, function () {
console.log('Example application listening on port 8080!');
});
关于ios - cordova 文件传输插件在 ios 模拟器中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31017152/