uploadAliOss.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. const OSS = require('ali-oss');
  2. import { getSTSToken } from '@/api/H5Camera';
  3. // 自定义请求头
  4. const headers = {
  5. // 指定Object的存储类型。
  6. 'x-oss-storage-class': 'Standard',
  7. // 指定Object的访问权限。
  8. 'x-oss-object-acl': 'private',
  9. // 通过文件URL访问文件时,指定以附件形式下载文件,下载后的文件名称定义为example.txt。
  10. 'Content-Disposition': 'attachment; filename="example.txt"',
  11. // 设置Object的标签,可同时设置多个标签。
  12. 'x-oss-tagging': 'Tag1=1&Tag2=2',
  13. // 指定PutObject操作时是否覆盖同名目标Object。此处设置为true,表示禁止覆盖同名Object。
  14. 'x-oss-forbid-overwrite': 'true',
  15. };
  16. export function dataURLtoFile(dataurl, filename) {
  17. let arr = dataurl.split(','),
  18. mime = arr[0].match(/:(.*?);/)[1],
  19. bstr = atob(arr[1]),
  20. n = bstr.length,
  21. u8arr = new Uint8Array(n);
  22. while (n--) {
  23. u8arr[n] = bstr.charCodeAt(n);
  24. }
  25. return new File([u8arr], filename, { type: mime });
  26. }
  27. const progress = (p, _checkpoint) => {
  28. // Object的上传进度。
  29. console.log(p);
  30. // 分片上传的断点信息。
  31. console.log(_checkpoint);
  32. };
  33. let credentials = null;
  34. async function uploadAliOss(base64, filename) {
  35. if (isCredentialsExpired(credentials)) {
  36. // 获取 STS token.
  37. const response = await getSTSToken();
  38. if (response.code != 200 || !response.data) {
  39. // 处理错误的HTTP状态码。
  40. let err = `获取STS令牌失败: ${response.msg}`;
  41. throw new Error(err);
  42. }
  43. credentials = await response.data;
  44. }
  45. const client = new OSS({
  46. region: 'cn-shanghai',
  47. bucket: process.env.NODE_ENV == 'production' ? 'ssbsfa-prd' : 'svs-test',
  48. accessKeyId: credentials.accessKeyId,
  49. accessKeySecret: credentials.accessKeySecret,
  50. stsToken: credentials.securityToken,
  51. secure: true,
  52. // 显式指定endpoint并修正格式
  53. // 使用标准区域节点配置
  54. region: 'oss-cn-shanghai',
  55. // 添加网络优化参数
  56. timeout: 30000,
  57. retryMax: 3,
  58. // 修正headers配置
  59. headers: {
  60. 'x-oss-forbid-overwrite': 'true',
  61. 'Cache-Control': 'no-cache',
  62. },
  63. });
  64. let file = dataURLtoFile(base64, filename);
  65. const regex = /^data:image\/(\w+);base64,/; // 正则表达式匹配base64数据头部
  66. const matches = base64.match(regex);
  67. let fileName = filename;
  68. if (matches && matches.length === 2) {
  69. matches[1]; // 返回第一个捕获组,即文件扩展名
  70. fileName = filename + '.' + matches[1];
  71. }
  72. try {
  73. const result = await client.put(fileName, file);
  74. console.log(result);
  75. return result;
  76. } catch (e) {
  77. console.error('OSS Upload Error Details:', {
  78. code: e.code,
  79. message: e.message,
  80. requestId: e.requestId,
  81. hostId: e.hostId,
  82. });
  83. throw new Error(`文件上传失败: ${e.code} - ${e.message}`);
  84. }
  85. }
  86. /**
  87. * 判断临时凭证是否到期。
  88. **/
  89. function isCredentialsExpired(credentials) {
  90. if (!credentials) {
  91. return true;
  92. }
  93. const expireDate = new Date(credentials.expiration);
  94. const now = new Date();
  95. // 如果有效期不足一分钟,视为过期。
  96. return expireDate.getTime() - now.getTime() <= 60000;
  97. }
  98. export default uploadAliOss;