Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/429.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript cordova插件文件传输:如何使用签名URL将文件上载到S3?_Javascript_Android_Cordova_Amazon S3_Ionic - Fatal编程技术网

Javascript cordova插件文件传输:如何使用签名URL将文件上载到S3?

Javascript cordova插件文件传输:如何使用签名URL将文件上载到S3?,javascript,android,cordova,amazon-s3,ionic,Javascript,Android,Cordova,Amazon S3,Ionic,我可以使用文件选择器和常规的XMLHttpRequest(我用来测试S3设置)上传到S3,但我不知道如何使用cordova文件传输插件成功完成上传 我认为这要么与插件没有构造正确的可签名请求有关,要么与插件不喜欢给定的本地文件uri有关。我尝试过处理从标题到uri类型的每一个参数,但这些文档没有太大帮助,插件源代码是bolognese 请求需要签名匹配的字符串如下所示: PUT 1391784394 x-amz-acl:public-read /the-app/317fdf654f9e329

我可以使用文件选择器和常规的
XMLHttpRequest
(我用来测试S3设置)上传到S3,但我不知道如何使用cordova文件传输插件成功完成上传

我认为这要么与插件没有构造正确的可签名请求有关,要么与插件不喜欢给定的本地文件uri有关。我尝试过处理从标题到uri类型的每一个参数,但这些文档没有太大帮助,插件源代码是bolognese

请求需要签名匹配的字符串如下所示:

PUT


1391784394
x-amz-acl:public-read
/the-app/317fdf654f9e3299f238d97d39f10fb1

有什么想法,或者可能是一个工作代码示例吗?

我在这个插件中遇到了这样的问题

我发现上传带有签名的文件的唯一有效方法是Christophe Coenraets的方法:

使用此方法,您将能够使用cordova插件文件传输上传您的文件

首先,我想在服务器上使用aws sdk使用getSignedUrl()进行签名 它返回已签名的链接,您只需上传到该链接即可

但是,使用插件,它总是以403结尾:签名不匹配


它可能与content length参数有关,但我现在还没有找到一个使用aws sdk和插件的有效解决方案,但我只是花了几天时间来解决这个问题,以防其他人遇到问题,这就是如何使用AWS SDK的javascript版本上传图像以创建预签名URL的方法

解决此问题的关键在于从Amazon返回的XML
SignatureDesNotMatch
错误的
StringToSign
元素。在我的例子中,它看起来像这样:

<StringToSign>
    PUT\n\nmultipart/form-data; boundary=+++++org.apache.cordova.formBoundary\n1481366396\n/bucketName/fileName.jpg
</StringToSign>
var AWS = require('aws-sdk');

var s3 = new AWS.S3(options = {
    endpoint: 'https://s3-eu-west-1.amazonaws.com',
    accessKeyId: "ACCESS_KEY",
    secretAccessKey: "SECRET_KEY"
});

var params = {
    Bucket: 'bucketName',
    Key: imageName,
    Expires: 60
};

var signedUrl = s3.getSignedUrl('putObject', params);

//return signedUrl
PUT

multipart/form-data; boundary=+++++org.apache.cordova.formBoundary
1481366396
/bucketName/fileName.jpg
这产生了一个类似于OP的签名字符串:

PUT


1481366396
/bucketName/fileName.jpg
在客户端,我将这个预先签名的URL与
cordova plugin file transfer
一起使用,就像这样(我使用的是爱奥尼亚2,因此插件被包装在其本机包装中):

运行代码生成的签名与错误不匹配,
元素中的字符串如下所示:

<StringToSign>
    PUT\n\nmultipart/form-data; boundary=+++++org.apache.cordova.formBoundary\n1481366396\n/bucketName/fileName.jpg
</StringToSign>
var AWS = require('aws-sdk');

var s3 = new AWS.S3(options = {
    endpoint: 'https://s3-eu-west-1.amazonaws.com',
    accessKeyId: "ACCESS_KEY",
    secretAccessKey: "SECRET_KEY"
});

var params = {
    Bucket: 'bucketName',
    Key: imageName,
    Expires: 60
};

var signedUrl = s3.getSignedUrl('putObject', params);

//return signedUrl
PUT

multipart/form-data; boundary=+++++org.apache.cordova.formBoundary
1481366396
/bucketName/fileName.jpg
因此,我们可以看到,
cordova plugin file transfer
在其自己的
内容类型
标题中添加了导致签名字符串不一致的内容。在与传递到upload方法中的options对象相关的

headers: A map of header name/header values. Use an array to specify more than one value. On iOS, FireOS, and Android, if a header named Content-Type is present, multipart form data will NOT be used. (Object)
因此,基本上,如果没有设置
内容类型
标题,它将默认为多部分表单数据

现在我们知道了问题的原因,这是一个非常简单的解决方法。在服务器端,我向传递给S3
getSignedUrl
方法的
params
对象添加了一个
ContentType

var params = {
    Bucket: 'bucketName',
    Key: imageName,
    Expires: 60,
    ContentType: 'image/jpeg' // <---- content type added here
};
嘿,普雷斯托!上传现在可以按预期工作了