![](/img/trans.png)
[英]s3 isn't uploading file and getting error of SignatureDoesNotMatch
[英]Direct uploading to AWS S3 : SignatureDoesNotMatch only for IE
我使用 Amazon Web Service S3 上傳和存儲我的文件。 由於這個預簽名的 url,我使用 AWS Sdk 為 Node.js 服務器端生成了一個預簽名的 url,以直接從瀏覽器上傳文件。
這個怎么運作
服務器端我有一個方法,它返回預簽名的 url。
AWS.config.loadFromPath(__dirname + '/../properties/aws-config.json');
AWS.config.region = 'eu-west-1';
//Credentials are loaded
var s3 = new AWS.S3();
var docId = req.query.doc;
var params = {
Bucket: res.locals.user.bucketId,
Key: docId+"."+req.query.fileExtension,
ACL : "bucket-owner-read",
ContentType : req.query.fileType
};
s3.getSignedUrl('putObject', params, function (err, url) {
if(url){
res.writeHead(200);
var result = {
AWSUrl : url
};
//Generates pre signed URL with signature param
res.end(JSON.stringify(result));
}
}
我直接將我的文件上傳到 S3 客戶端
var loadToAWSS3 = function(url, file, inputFileId){
var data = new FormData();
data.append('file', file);
$.ajax({
url: url,//url getted from server-side method
type: 'PUT',
data : data,
headers: {
'Content-Type': file.type
},
processData: false,
xhr: function() {
var myXhr = $.ajaxSettings.xhr();
if(myXhr.upload){
myXhr.upload.addEventListener('progress',function(e){
if(e.lengthComputable){
var max = e.total;
var current = e.loaded;
var percentage = (current * 100)/max;
//stuff to handle progress...
}
},
false);
}
return myXhr;
},
statusCode: {
200: function () {
//some stuff
}
});
}
Chrome 和 Firefox 行為
按預期工作,獲取預簽名的 url,然后上傳文件,我可以在我的 AWS S3 控制台中看到它。
可愛的 IE 11
SignatureDoesNotMatch 錯誤! IE 向 Content-Type 請求標頭添加了一些 AWS 不期望的額外內容,這會導致簽名比較中出現錯誤。 服務器端,Sdk 生成簽名基於:
ContentType : req.query.fileType //(something like application/pdf)
而當我用 IE 調試器檢查請求時,我看到
Content-Type application/pdf, multipart/form-data; boundary=---------------------------7df2f3283091c
在 Chrome 中,我的請求標頭很好
Content-Type: application/pdf
我該怎么做才能刪除這個 IE 額外的 Content-Type ? 如果不可能,如何在發送請求之前生成這些額外的東西,以便在簽名中獲取帶有額外內容的預簽名 url?
好吧,我終於想通了。
使用 FormData() 模擬您通過表單發送文件。 這就是為什么 IE 總是添加
multipart/form-data; boundary=---------------------------7**********
為了解決這個問題,我使用帶有 XMLHttpRequest 的原始 Javascript 多虧了這個答案
var xmlHttpRequest = new XMLHttpRequest();
xmlHttpRequest.open('PUT', url, true);
xmlHttpRequest.setRequestHeader('Content-Type', file.type);
xmlHttpRequest.send(file);
它適用於 Chrome、Firefox、IE 11(我沒有使用 IE<11 進行測試,但根據W3Schools它適用於 IE7+)。 IE 不再有額外的內容類型。
希望這可以幫助
如果您有權訪問 xhr,您可以執行以下操作:
var _send = xhr.send;
xhr.send = function() {
_send.call(xhr, file);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.