[
  {
    "path": "README.md",
    "content": "# OSS in Browser\n\nPlay with OSS right in the browser!\n\n![Demo](screenshot.png?raw=true \"OSS in Browser\")\n\n## Browser support\n\n- IE >= 10 & Edge\n- Major versions of Chrome/Firefox/Safari\n- Major versions of Android/iOS/WP\n\n## Setup\n\n### Bucket setup\n\nAs browser-side javascript involves CORS operations. You need to setup\nyour bucket CORS rules to allow CORS operations:\n\n- set allowed origins to '*'\n- allowed methods to 'PUT, GET, POST, DELETE, HEAD'\n- set allowed headers to '*'\n- expose 'ETag' in expose headers\n\n### STS setup\n\nAs we don't want to expose the accessKeyId/accessKeySecret in the\nbrowser, a [common practice][oss-sts] is to use STS to grant temporary\naccess.\n\n### App setup\n\nFill in your appServer address and bucket name in `app.js`:\n\n```js\nvar appServer = '<your STS app server>';\nvar bucket = '<your bucket name>';\nvar region = 'oss-cn-hangzhou';\n```\n\nAnd then open `index.html` in your browser.\n\n### STS App server\n\nA sample app server can be found [here][node-sts-app-server].\n\n### IE Compatibility\n\nYou may need include the promise polyfill for IE:\n\n```html\n<script src=\"https://www.promisejs.org/polyfills/promise-6.1.0.js\"></script>\n```\n\n\n[node-sts-app-server]: https://github.com/rockuw/node-sts-app-server\n[oss-sts]: https://help.aliyun.com/document_detail/oss/practice/ram_guide.html\n"
  },
  {
    "path": "app.js",
    "content": "'use strict';\n\nvar appServer = 'http://localhost:3000';\nvar bucket = '<bucket-name>';\nvar region = 'oss-cn-hangzhou';\n\nvar urllib = OSS.urllib;\nvar Buffer = OSS.Buffer;\nvar OSS = OSS.Wrapper;\nvar STS = OSS.STS;\n\n// Play without STS. NOT SAFE! Because access key id/secret are\n// exposed in web page.\n\n// var client = new OSS({\n//   region: 'oss-cn-hangzhou',\n//   accessKeyId: '<access-key-id>',\n//   accessKeySecret: '<access-key-secret>',\n//   bucket: '<bucket-name>'\n// });\n//\n// var applyTokenDo = function (func) {\n//   return func(client);\n// };\n\nvar applyTokenDo = function (func) {\n  var url = appServer;\n  return urllib.request(url, {\n    method: 'GET'\n  }).then(function (result) {\n    var creds = JSON.parse(result.data);\n    var client = new OSS({\n      region: region,\n      accessKeyId: creds.AccessKeyId,\n      accessKeySecret: creds.AccessKeySecret,\n      stsToken: creds.SecurityToken,\n      bucket: bucket\n    });\n\n    return func(client);\n  });\n};\n\nvar progress = function (p) {\n  return function (done) {\n    var bar = document.getElementById('progress-bar');\n    bar.style.width = Math.floor(p * 100) + '%';\n    bar.innerHTML = Math.floor(p * 100) + '%';\n    done();\n  }\n};\n\nvar uploadFile = function (client) {\n  var file = document.getElementById('file').files[0];\n  var key = document.getElementById('object-key-file').value.trim() || 'object';\n  console.log(file.name + ' => ' + key);\n\n  return client.multipartUpload(key, file, {\n    progress: progress\n  }).then(function (res) {\n    console.log('upload success: %j', res);\n    return listFiles(client);\n  });\n};\n\nvar uploadContent = function (client) {\n  var content = document.getElementById('file-content').value.trim();\n  var key = document.getElementById('object-key-content').value.trim() || 'object';\n  console.log('content => ' + key);\n\n  return client.put(key, new Buffer(content)).then(function (res) {\n    return listFiles(client);\n  });\n};\n\nvar listFiles = function (client) {\n  var table = document.getElementById('list-files-table');\n  console.log('list files');\n\n  return client.list({\n    'max-keys': 100\n  }).then(function (result) {\n    var objects = result.objects.sort(function (a, b) {\n      var ta = new Date(a.lastModified);\n      var tb = new Date(b.lastModified);\n      if (ta > tb) return -1;\n      if (ta < tb) return 1;\n      return 0;\n    });\n\n    var numRows = table.rows.length;\n    for (var i = 1; i < numRows; i ++) {\n      table.deleteRow(table.rows.length - 1);\n    }\n\n    for (var i = 0; i < Math.min(3, objects.length); i ++) {\n      var row = table.insertRow(table.rows.length);\n      row.insertCell(0).innerHTML = objects[i].name;\n      row.insertCell(1).innerHTML = objects[i].size;\n      row.insertCell(2).innerHTML = objects[i].lastModified;\n    }\n  });\n};\n\nvar downloadFile = function (client) {\n  var object = document.getElementById('dl-object-key').value.trim();\n  var filename = document.getElementById('dl-file-name').value.trim();\n  console.log(object + ' => ' + filename);\n\n  var result = client.signatureUrl(object, {\n    response: {\n      'content-disposition': 'attachment; filename=\"' + filename + '\"'\n    }\n  });\n  window.location = result;\n\n  return result;\n};\n\nwindow.onload = function () {\n  document.getElementById('file-button').onclick = function () {\n    applyTokenDo(uploadFile);\n  }\n\n  document.getElementById('content-button').onclick = function () {\n    applyTokenDo(uploadContent);\n  }\n\n  document.getElementById('list-files-button').onclick = function () {\n    applyTokenDo(listFiles);\n  }\n\n  document.getElementById('dl-button').onclick = function () {\n    applyTokenDo(downloadFile);\n  }\n\n  applyTokenDo(listFiles);\n};\n"
  },
  {
    "path": "index.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n  <title>OSS in Browser</title>\n  <script src=\"https://www.promisejs.org/polyfills/promise-6.1.0.js\"></script>\n  <script type=\"text/javascript\" src=\"http://gosspublic.alicdn.com/aliyun-oss-sdk.min.js\"></script>\n  <script type=\"text/javascript\" src=\"app.js\"></script>\n  <link rel=\"stylesheet\" href=\"bootstrap.min.css\" />\n  <link rel=\"stylesheet\" href=\"style.css\" />\n</head>\n<body>\n  <div id=\"main\">\n    <div class=\"page-header\">\n      <h1>OSS <small>in</small> Browser</h1>\n    </div>\n    <table>\n      <tr>\n        <td>\n          <div class=\"panel panel-primary\">\n            <div class=\"panel-heading\">Upload file</div>\n            <div class=\"panel-body\">\n              <form action=\"\" class=\"form-horizontal\">\n                <div class=\"form-group\">\n                  <label>Select file</label>\n                  <input type=\"file\" id=\"file\" />\n                </div>\n                <div class=\"form-group\">\n                  <label>Store as</label>\n                  <input type=\"text\" class=\"form-control\" id=\"object-key-file\" value=\"object\" />\n                </div>\n                <div class=\"form-group\">\n                  <input type=\"button\" class=\"btn btn-primary\" id=\"file-button\" value=\"Upload\" />\n                </div>\n              </form>\n              <br />\n              <div class=\"progress\">\n                <div id=\"progress-bar\"\n                     class=\"progress-bar\"\n                     role=\"progressbar\"\n                     aria-valuenow=\"0\"\n                     aria-valuemin=\"0\"\n                     aria-valuemax=\"100\" style=\"min-width: 2em;\">\n                  0%\n                </div>\n              </div>\n            </div>\n          </div>\n        </td>\n        <td>\n          <div class=\"panel panel-success\">\n            <div class=\"panel-heading\">Upload content</div>\n            <div class=\"panel-body\">\n              <form action=\"\" class=\"form-horizontal\">\n                <div class=\"form-group\">\n                  <label>Content</label>\n                  <textarea class=\"form-control\" id=\"file-content\" rows=\"3\">Hello, OSS!</textarea>\n                </div>\n                <div class=\"form-group\">\n                  <label>Store as</label>\n                  <input type=\"text\" class=\"form-control\" id=\"object-key-content\" value=\"object\" />\n                </div>\n                <div class=\"form-group\">\n                  <input type=\"button\" class=\"btn btn-primary\" id=\"content-button\" value=\"Save\" />\n                </div>\n              </form>\n            </div>\n          </div>\n        </td>\n      </tr>\n      <tr>\n        <td>\n          <div class=\"panel panel-info\">\n            <div class=\"panel-heading\">List files</div>\n            <div class=\"panel-body\">\n              <table class=\"table table-striped\" id=\"list-files-table\">\n                <tr>\n                  <th>Key</th>\n                  <th>Size</th>\n                  <th>LastModified</th>\n                </tr>\n              </table>\n              <input type=\"button\" class=\"btn btn-primary\" id=\"list-files-button\" value=\"Refresh\" />\n            </div>\n          </div>\n        </td>\n        <td>\n          <div class=\"panel panel-warning\">\n            <div class=\"panel-heading\">Download file</div>\n            <div class=\"panel-body\">\n              <form action=\"\" class=\"form-horizontal\">\n                <div class=\"form-group\">\n                  <label>Object key</label>\n                  <input type=\"text\" class=\"form-control\" id=\"dl-object-key\" value=\"object\" />\n                </div>\n                <div class=\"form-group\">\n                  <label>Save as</label>\n                  <input type=\"text\" class=\"form-control\" id=\"dl-file-name\" value=\"filename\" />\n                </div>\n                <div class=\"form-group\">\n                  <input type=\"button\" class=\"btn btn-primary\" id=\"dl-button\" value=\"Download\" />\n                </div>\n              </form>\n            </div>\n          </div>\n        </td>\n      </tr>\n      <tr>\n        <td colspan=\"2\">\n          Powered by\n          <a href=\"https://www.aliyun.com/product/oss\">OSS</a> &\n          <a href=\"https://github.com/ali-sdk/ali-oss\">ali-oss</a></td>\n      </tr>\n    </table>\n  </div>\n</body>\n</html>\n"
  },
  {
    "path": "style.css",
    "content": "body {\n    text-align: center;\n}\n\n#main {\n    text-align: left;\n    width: 1000px;\n    margin: 0 auto;\n}\n\ntable tr td > div {\n    width: 480px;\n    height: 300px;\n    margin: 10px;\n}\n\ntable tr td > div > div.panel-body {\n    margin-left: 5px;\n    margin-right: 5px;\n}\n"
  }
]