-
Notifications
You must be signed in to change notification settings - Fork 566
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
370 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<title>Form 表单简单上传</title> | ||
<style>h1, h2 {font-weight: normal;}#msg {margin-top:10px;}</style> | ||
</head> | ||
<body> | ||
|
||
<h1>Form 表单简单上传</h1> | ||
<div>最低兼容到 IE6 上传,使用 policy 签名保护,不支持 onprogress</div> | ||
|
||
<form id="form" target="submitTarget" action="" method="post" enctype="multipart/form-data" accept="*/*"> | ||
<input id="fileSelector" name="file" type="file"> | ||
<input id="submitBtn" type="button" value="提交"> | ||
</form> | ||
<iframe id="submitTarget" name="submitTarget" style="display:none;" frameborder="0"></iframe> | ||
|
||
<div id="msg"></div> | ||
|
||
<script src="common/cos-auth.min.js"></script> | ||
<script src="common/crypto.js"></script> | ||
<script> | ||
(function () { | ||
// 请求用到的参数 | ||
var Bucket = 'test-1250000000'; | ||
var Region = 'ap-guangzhou'; | ||
var protocol = location.protocol === 'https:' ? 'https:' : 'http:'; | ||
var prefix = protocol + '//' + Bucket + '.cos.' + Region + '.myqcloud.com/'; | ||
var fileSelector = document.getElementById('fileSelector'); | ||
var form = document.getElementById('form'); | ||
form.action = prefix; | ||
|
||
// 对更多字符编码的 url encode 格式 | ||
var camSafeUrlEncode = function (str) { | ||
return encodeURIComponent(str) | ||
.replace(/!/g, '%21') | ||
.replace(/'/g, '%27') | ||
.replace(/\(/g, '%28') | ||
.replace(/\)/g, '%29') | ||
.replace(/\*/g, '%2A'); | ||
}; | ||
|
||
// 获取权限策略 | ||
var getPostPolicyCredentials = function (opt, callback) { | ||
// var now = Math.round(Date.now() / 1000); | ||
// var exp = now + 900; | ||
// var qKeyTime = now + ';' + exp; | ||
// var qSignAlgorithm = 'sha1'; | ||
// var policy = JSON.stringify({ | ||
// 'expiration': new Date(exp * 1000).toISOString(), | ||
// 'conditions': [ | ||
// // {'acl': opt.ACL || 'default'}, | ||
// {'bucket': opt.Bucket}, | ||
// // ['starts-with', '$key', opt.Key], | ||
// // ['starts-with', '$Content-Type', 'image/'], | ||
// // ['starts-with', '$success_action_redirect', redirectUrl], | ||
// // ['eq', '$x-cos-server-side-encryption', 'AES256'], | ||
// {'q-sign-algorithm': qSignAlgorithm}, | ||
// {'q-ak': SecretId}, | ||
// {'q-sign-time': qKeyTime} | ||
// ] | ||
// }); | ||
// | ||
// // 步骤一:生成 SignKey | ||
// var signKey = CryptoJS.HmacSHA1(qKeyTime, SecretKey).toString(); | ||
// | ||
// // 步骤二:生成 StringToSign | ||
// var stringToSign = CryptoJS.SHA1(policy).toString(); | ||
// | ||
// // 步骤三:生成 Signature | ||
// var qSignature = CryptoJS.HmacSHA1(stringToSign, signKey).toString(); | ||
// | ||
// callback(null, { | ||
// policy: btoa(policy), | ||
// qSignAlgorithm: qSignAlgorithm, | ||
// qAk: SecretId, | ||
// qKeyTime: qKeyTime, | ||
// qSignature: qSignature, | ||
// }); | ||
|
||
var url = 'http://127.0.0.1:3000/post-policy?key=' + encodeURIComponent(opt.Key); | ||
var xhr = new XMLHttpRequest(); | ||
xhr.open('GET', url, true); | ||
xhr.onreadystatechange = function (e) { | ||
if (xhr.readyState === 4) { | ||
if (xhr.status === 200) { | ||
var credentials; | ||
try { | ||
credentials = (new Function('return ' + xhr.responseText))(); | ||
} catch (e) {} | ||
if (credentials) { | ||
callback(null, credentials); | ||
} else { | ||
console.error(xhr.responseText); | ||
callback('获取签名出错'); | ||
} | ||
} else { | ||
callback('获取签名出错'); | ||
} | ||
} | ||
}; | ||
xhr.send(); | ||
}; | ||
|
||
// 监听上传完成 | ||
var Key; | ||
var submitTarget = document.getElementById('submitTarget'); | ||
var showMessage = function (err, data) { | ||
console.log(err || data); | ||
document.getElementById('msg').innerText = err ? err : ('上传成功,ETag=' + data.ETag); | ||
}; | ||
submitTarget.onload = function () { | ||
var search; | ||
try { | ||
search = submitTarget.contentWindow.location.search.substr(1); | ||
} catch (e) { | ||
showMessage('文件 ' + Key + ' 上传失败'); | ||
} | ||
if (search) { | ||
var items = search.split('&'); | ||
var i, arr, data = {}; | ||
for (i = 0; i < items.length; i++) { | ||
arr = items[i].split('='); | ||
data[arr[0]] = decodeURIComponent(arr[1] || ''); | ||
} | ||
showMessage(null, {url: prefix + camSafeUrlEncode(Key).replace(/%2F/g, '/'), ETag: data.etag}); | ||
} else { | ||
} | ||
}; | ||
|
||
var setFormField = function (key, value) { | ||
var el = document.getElementById(key); | ||
if (!el) { | ||
el = document.createElement('input'); | ||
el.hidden = true; | ||
el.id = key; | ||
el.name = key; | ||
form.insertBefore(el, fileSelector); | ||
} | ||
el.setAttribute('value', value); // 需要保证 file 在表单最后 | ||
el.value = value; | ||
}; | ||
|
||
// 发起上传 | ||
document.getElementById('submitBtn').onclick = function (e) { | ||
var filePath = document.getElementById('fileSelector').value; | ||
if (!filePath) { | ||
document.getElementById('msg').innerText = '未选择上传文件'; | ||
return; | ||
} | ||
Key = 'dir/' + filePath.match(/[\\\/]?([^\\\/]+)$/)[1]; // 这里指定上传目录和文件名 | ||
|
||
// 获取签名保护字段 | ||
getPostPolicyCredentials({ | ||
Key: Key, | ||
}, function (err, credentials) { | ||
|
||
// 在当前目录下放一个空的 empty.html 以便让接口上传完成跳转回来 | ||
setFormField('success_action_redirect', location.href.substr(0, location.href.lastIndexOf('/') + 1) + 'empty.html'); | ||
setFormField('key', Key); | ||
|
||
// 使用 policy 签名保护格式 | ||
credentials.securityToken && setFormField('x-cos-security-token', credentials.securityToken); | ||
setFormField('q-sign-algorithm', credentials.qSignAlgorithm); | ||
setFormField('q-ak', credentials.qAk); | ||
setFormField('q-key-time', credentials.qKeyTime); | ||
setFormField('q-signature', credentials.qSignature); | ||
setFormField('policy', credentials.policy); | ||
|
||
// 提交表单 | ||
form.submit(); | ||
|
||
}); | ||
}; | ||
})(); | ||
</script> | ||
|
||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<title>Ajax Post 上传</title> | ||
<style> | ||
h1, h2 { | ||
font-weight: normal; | ||
} | ||
|
||
#msg { | ||
margin-top: 10px; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
|
||
<h1>Ajax Post 上传</h1> | ||
|
||
<input id="fileSelector" type="file"> | ||
<input id="submitBtn" type="submit"> | ||
|
||
<div id="msg"></div> | ||
|
||
<script src="common/cos-auth.min.js"></script> | ||
<script src="common/crypto.js"></script> | ||
<script> | ||
(function () { | ||
|
||
// 请求用到的参数 | ||
var Bucket = 'test-1250000000'; | ||
var Region = 'ap-guangzhou'; | ||
var protocol = location.protocol === 'https:' ? 'https:' : 'http:'; | ||
var prefix = protocol + '//' + Bucket + '.cos.' + Region + '.myqcloud.com/'; | ||
|
||
// 对更多字符编码的 url encode 格式 | ||
var camSafeUrlEncode = function (str) { | ||
return encodeURIComponent(str) | ||
.replace(/!/g, '%21') | ||
.replace(/'/g, '%27') | ||
.replace(/\(/g, '%28') | ||
.replace(/\)/g, '%29') | ||
.replace(/\*/g, '%2A'); | ||
}; | ||
|
||
// 获取权限策略 | ||
var getPostPolicyCredentials = function (opt, callback) { | ||
var url = 'http://127.0.0.1:3000/post-policy?key=' + encodeURIComponent(opt.Key); | ||
var xhr = new XMLHttpRequest(); | ||
xhr.open('GET', url, true); | ||
xhr.onreadystatechange = function (e) { | ||
if (xhr.readyState === 4) { | ||
if (xhr.status === 200) { | ||
var credentials; | ||
try { | ||
credentials = (new Function('return ' + xhr.responseText))(); | ||
} catch (e) {} | ||
if (credentials) { | ||
callback(null, credentials); | ||
} else { | ||
console.error(xhr.responseText); | ||
callback('获取签名出错'); | ||
} | ||
} else { | ||
callback('获取签名出错'); | ||
} | ||
} | ||
}; | ||
xhr.send(); | ||
}; | ||
|
||
// 上传文件 | ||
var uploadFile = function (file, callback) { | ||
var Key = 'dir/' + file.name; // 这里指定上传目录和文件名 | ||
getPostPolicyCredentials({ | ||
Bucket: Bucket, | ||
Key: Key, | ||
ACL: 'default' | ||
}, function (err, credentials) { | ||
var fd = new FormData(); | ||
|
||
// 在当前目录下放一个空的 empty.html 以便让接口上传完成跳转回来 | ||
fd.append('key', Key); | ||
|
||
// // 使用普通签名格式 | ||
// fd.append('Signature', credentials.Authorization); | ||
// fd.append('x-cos-security-token', credentials.XCosSecurityToken || ''); | ||
|
||
// 使用 policy 签名保护格式 | ||
credentials.securityToken && fd.append('x-cos-security-token', credentials.securityToken); | ||
fd.append('q-sign-algorithm', credentials.qSignAlgorithm); | ||
fd.append('q-ak', credentials.qAk); | ||
fd.append('q-key-time', credentials.qKeyTime); | ||
fd.append('q-signature', credentials.qSignature); | ||
fd.append('policy', credentials.policy); | ||
|
||
// 文件内容 | ||
fd.append('file', file); | ||
|
||
// xhr | ||
var url = prefix; | ||
var xhr = new XMLHttpRequest(); | ||
xhr.open('POST', url, true); | ||
xhr.upload.onprogress = function (e) { | ||
console.log('上传进度 ' + (Math.round(e.loaded / e.total * 10000) / 100) + '%'); | ||
}; | ||
xhr.onload = function () { | ||
if (Math.floor(xhr.status / 100) === 2) { | ||
var ETag = xhr.getResponseHeader('etag'); | ||
callback(null, {url: prefix + camSafeUrlEncode(Key).replace(/%2F/g, '/'), ETag: ETag}); | ||
} else { | ||
callback('文件 ' + Key + ' 上传失败,状态码:' + xhr.status); | ||
} | ||
}; | ||
xhr.onerror = function () { | ||
callback('文件 ' + Key + ' 上传失败,请检查是否没配置 CORS 跨域规则'); | ||
}; | ||
xhr.send(fd); | ||
}); | ||
}; | ||
|
||
// 监听表单提交 | ||
document.getElementById('submitBtn').onclick = function (e) { | ||
var file = document.getElementById('fileSelector').files[0]; | ||
if (!file) { | ||
document.getElementById('msg').innerText = '未选择上传文件'; | ||
return; | ||
} | ||
file && uploadFile(file, function (err, data) { | ||
console.log(err || data); | ||
document.getElementById('msg').innerText = err ? err : ('上传成功,ETag=' + data.ETag); | ||
}); | ||
}; | ||
})(); | ||
</script> | ||
|
||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.