index.html 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. <!doctype html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta
  6. name="viewport"
  7. content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
  8. />
  9. <meta http-equiv="X-UA-Compatible" content="ie=edge" />
  10. <title>cos-js-sdk-v5</title>
  11. <style>
  12. body {
  13. font-family: 'Microsoft YaHei';
  14. }
  15. .page {
  16. min-width: 1000px;
  17. margin: 0 auto;
  18. padding: 0 50px;
  19. }
  20. .main-wrap {
  21. float: left;
  22. width: 100%;
  23. }
  24. .main {
  25. margin-right: 700px;
  26. margin-bottom: 20px;
  27. display: none;
  28. }
  29. .main.show {
  30. display: block;
  31. }
  32. .siderbar {
  33. float: left;
  34. width: 600px;
  35. margin-left: -600px;
  36. margin-bottom: 20px;
  37. padding-top: 60px;
  38. }
  39. .result {
  40. line-height: 1.3;
  41. font-size: 13px;
  42. font-family: monospace;
  43. border: 1px solid #006eff;
  44. margin: 0;
  45. height: 200px;
  46. overflow: auto;
  47. box-sizing: border-box;
  48. padding: 5px;
  49. }
  50. h1 {
  51. font-weight: normal;
  52. color: #333;
  53. }
  54. a {
  55. color: #006eff;
  56. background-color: transparent;
  57. padding: 8px 16px;
  58. line-height: 1.3;
  59. display: inline-block;
  60. text-align: center;
  61. margin: 0 8px 8px 0;
  62. border: 1px solid #006eff;
  63. font-size: 14px;
  64. text-decoration: none;
  65. }
  66. a:hover {
  67. color: #fff;
  68. background-color: #006eff;
  69. }
  70. hr {
  71. border: 0;
  72. border-top: 1px solid #006eff;
  73. }
  74. .demo-select-content {
  75. display: inline-block;
  76. font-size: 0;
  77. margin-left: 20px;
  78. }
  79. .demo-select-content div {
  80. display: inline-block;
  81. font-size: 16px;
  82. border: solid 1px #ddd;
  83. padding: 2px 6px;
  84. cursor: pointer;
  85. }
  86. .demo-select-content div.active {
  87. border-color: #006eff;
  88. color: #006eff;
  89. }
  90. </style>
  91. </head>
  92. <body>
  93. <div class="page">
  94. <h1>
  95. cos-js-sdk-v5
  96. <div class="demo-select-content">
  97. <div class="active" id="showCosDemo">cos demo</div>
  98. <div id="showCiDemo">ci demo</div>
  99. </div>
  100. </h1>
  101. <div class="main-wrap">
  102. <div class="main cos-main show"></div>
  103. <div class="main ci-main"></div>
  104. </div>
  105. <div class="siderbar">
  106. <pre class="result"></pre>
  107. </div>
  108. </div>
  109. <script src="../dist/cos-js-sdk-v5.js"></script>
  110. <script src="./demo.js"></script>
  111. <script type="module" src="./CIDemos/index.js"></script>
  112. <script>
  113. (function () {
  114. var showCosDemoBtn = document.querySelector('#showCosDemo');
  115. var showCiDemobtn = document.querySelector('#showCiDemo');
  116. var cosMain = document.querySelector('.cos-main');
  117. var ciMain = document.querySelector('.ci-main');
  118. showCosDemoBtn.addEventListener('click', function (e) {
  119. showCosDemoBtn.className = 'active';
  120. showCiDemobtn.className = '';
  121. cosMain.className = 'main cos-main show';
  122. ciMain.className = 'main cos-main';
  123. });
  124. showCiDemobtn.addEventListener('click', function (e) {
  125. showCosDemoBtn.className = '';
  126. showCiDemobtn.className = 'active';
  127. cosMain.className = 'main cos-main';
  128. ciMain.className = 'main cos-main show';
  129. });
  130. // config 替换成自己的存储桶和账号信息
  131. var config = {
  132. Bucket: 'test-1250000000',
  133. Region: 'ap-guangzhou',
  134. Uin: '10001',
  135. };
  136. var getAuthorization = function (options, callback) {
  137. // 格式一、(推荐)后端通过获取临时密钥给到前端,前端计算签名
  138. // 服务端 JS 和 PHP 例子:https://github.com/tencentyun/cos-js-sdk-v5/blob/master/server/
  139. // 服务端其他语言参考 COS STS SDK :https://github.com/tencentyun/qcloud-cos-sts-sdk
  140. var url = '/sts'; // 如果是 npm run sts.js 起的 nodejs server,使用这个
  141. var xhr = new XMLHttpRequest();
  142. xhr.open('POST', url, true);
  143. xhr.setRequestHeader('Content-Type', 'application/json');
  144. xhr.onload = function (e) {
  145. try {
  146. var data = JSON.parse(e.target.responseText);
  147. var credentials = data.credentials;
  148. } catch (e) {}
  149. if (!data || !credentials) {
  150. return logger.error('credentials invalid:\n' + JSON.stringify(data, null, 2));
  151. }
  152. callback({
  153. TmpSecretId: credentials.tmpSecretId,
  154. TmpSecretKey: credentials.tmpSecretKey,
  155. SecurityToken: credentials.sessionToken,
  156. StartTime: data.startTime, // 时间戳,单位秒,如:1580000000,建议返回服务器时间作为签名的开始时间,避免用户浏览器本地时间偏差过大导致签名错误
  157. ExpiredTime: data.expiredTime, // 时间戳,单位秒,如:1580000000
  158. ScopeLimit: true, // 细粒度控制权限需要设为 true,会限制密钥只在相同请求时重复使用
  159. });
  160. };
  161. xhr.send(JSON.stringify(options.Scope));
  162. // // 格式二、(推荐)【细粒度控制权限】后端通过获取临时密钥给到前端,前端只有相同请求才重复使用临时密钥,后端可以通过 Scope 细粒度控制权限
  163. // // 服务端例子:https://github.com/tencentyun/qcloud-cos-sts-sdk/edit/master/scope.md
  164. // // var url = '../server/sts.php'; // 如果起的是 php server 用这个
  165. // var url = '/sts-scope'; // 如果是 npm run sts.js 起的 nodejs server,使用这个
  166. // var xhr = new XMLHttpRequest();
  167. // xhr.open('POST', url, true);
  168. // xhr.setRequestHeader('Content-Type', 'application/json');
  169. // xhr.onload = function (e) {
  170. // try {
  171. // var data = JSON.parse(e.target.responseText);
  172. // var credentials = data.credentials;
  173. // } catch (e) {
  174. // }
  175. // if (!data || !credentials) {
  176. // return logger.error('credentials invalid:\n' + JSON.stringify(data, null, 2))
  177. // };
  178. // callback({
  179. // TmpSecretId: credentials.tmpSecretId,
  180. // TmpSecretKey: credentials.tmpSecretKey,
  181. // SecurityToken: credentials.sessionToken,
  182. // StartTime: data.startTime, // 时间戳,单位秒,如:1580000000,建议返回服务器时间作为签名的开始时间,避免用户浏览器本地时间偏差过大导致签名错误
  183. // ExpiredTime: data.expiredTime, // 时间戳,单位秒,如:1580000000
  184. // ScopeLimit: true, // 细粒度控制权限需要设为 true,会限制密钥只在相同请求时重复使用
  185. // });
  186. // };
  187. // xhr.send(JSON.stringify(options.Scope));
  188. // // 格式三、(不推荐,分片上传权限不好控制)前端每次请求前都需要通过 getAuthorization 获取签名,后端使用固定密钥或临时密钥计算签名返回给前端
  189. // // 服务端获取签名,请参考对应语言的 COS SDK:https://cloud.tencent.com/document/product/436/6474
  190. // // 注意:这种有安全风险,后端需要通过 method、pathname 严格控制好权限,比如不允许 put / 等
  191. // var method = (options.Method || 'get').toLowerCase();
  192. // var query = options.Query || {};
  193. // var headers = options.Headers || {};
  194. // var pathname = options.Pathname || '/';
  195. // // var url = 'http://127.0.0.1:3000/auth';
  196. // var url = '../server/auth.php';
  197. // var xhr = new XMLHttpRequest();
  198. // var data = {
  199. // method: method,
  200. // pathname: pathname,
  201. // query: query,
  202. // headers: headers,
  203. // };
  204. // xhr.open('POST', url, true);
  205. // xhr.setRequestHeader('content-type', 'application/json');
  206. // xhr.onload = function (e) {
  207. // try {
  208. // var data = JSON.parse(e.target.responseText);
  209. // } catch (e) {
  210. // }
  211. // if (!data || !data.authorization) return console.error('authorization invalid');
  212. // callback({
  213. // Authorization: data.authorization,
  214. // // SecurityToken: data.sessionToken, // 如果使用临时密钥,需要把 sessionToken 传给 SecurityToken
  215. // });
  216. // };
  217. // xhr.send(JSON.stringify(data));
  218. // // 格式四、(不推荐,适用于前端调试,避免泄露密钥)前端使用固定密钥计算签名
  219. // var authorization = COS.getAuthorization({
  220. // SecretId: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', // 可传固定密钥或者临时密钥
  221. // SecretKey: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', // 可传固定密钥或者临时密钥
  222. // Method: options.Method,
  223. // Pathname: options.Pathname,
  224. // Query: options.Query,
  225. // Headers: options.Headers,
  226. // Expires: 900,
  227. // });
  228. // callback({
  229. // Authorization: authorization,
  230. // // SecurityToken: credentials.sessionToken, // 如果使用临时密钥,需要传 SecurityToken
  231. // });
  232. };
  233. var cos = new COS({
  234. getAuthorization: getAuthorization,
  235. UploadCheckContentMd5: true,
  236. });
  237. var util = {
  238. createFile: function (options) {
  239. var buffer = new ArrayBuffer(options.size || 0);
  240. var arr = new Uint8Array(buffer);
  241. [].forEach.call(arr, function (char, i) {
  242. arr[i] = 0;
  243. });
  244. var opt = {};
  245. options.type && (opt.type = options.type);
  246. var blob = new Blob([buffer], options);
  247. return blob;
  248. },
  249. selectLocalFile: function (onChange) {
  250. var id = 'file_selector';
  251. var input = document.createElement('input');
  252. input.style = 'width:0;height:0;border:0;margin:0;padding:0;';
  253. input.type = 'file';
  254. input.id = id;
  255. input.onchange = function (e) {
  256. var files = this.files;
  257. if (!files.length) return;
  258. onChange && onChange(files);
  259. document.body.removeChild(input);
  260. };
  261. document.body.appendChild(input);
  262. input.click();
  263. },
  264. };
  265. // 对更多字符编码的 url encode 格式
  266. var camSafeUrlEncode = function (str) {
  267. return encodeURIComponent(str)
  268. .replace(/!/g, '%21')
  269. .replace(/'/g, '%27')
  270. .replace(/\(/g, '%28')
  271. .replace(/\)/g, '%29')
  272. .replace(/\*/g, '%2A');
  273. };
  274. var pre = document.querySelector('.result');
  275. var showLogText = function (text, color) {
  276. if (typeof text === 'object') {
  277. try {
  278. text = JSON.stringify(text);
  279. } catch (e) {}
  280. }
  281. var div = document.createElement('div');
  282. div.innerText = text;
  283. color && (div.style.color = color);
  284. pre.appendChild(div);
  285. pre.style.display = 'block';
  286. pre.scrollTop = pre.scrollHeight;
  287. };
  288. var logger = {
  289. log: function (text) {
  290. console.log.apply(console, arguments);
  291. var args = [].map.call(arguments, function (v) {
  292. return typeof v === 'object' ? JSON.stringify(v, null, 2) : v;
  293. });
  294. var logStr = args.join(' ');
  295. if (logStr.length > 1000000) {
  296. logStr =
  297. logStr.slice(0, 1000000) + '...content is too long, the first 1000000 characters are intercepted';
  298. }
  299. showLogText(logStr);
  300. },
  301. error: function (text) {
  302. console.error(text);
  303. showLogText(text, 'red');
  304. },
  305. };
  306. /**
  307. * 这里demo为了方便挂在了window上 实际使用请结合项目比如可使用模块导出
  308. * */
  309. window.config = config;
  310. window.cos = cos;
  311. window.util = util;
  312. window.logger = logger;
  313. window.camSafeUrlEncode = camSafeUrlEncode;
  314. })();
  315. </script>
  316. </body>
  317. </html>