├── README.md ├── app.js ├── cari.js ├── cari.png ├── custom.css ├── go-drive-logo.png ├── ss.jpg └── worker.js /README.md: -------------------------------------------------------------------------------- 1 | ![Go Drive](https://raw.githubusercontent.com/kulokenci/goindex-drive/master/go-drive-logo.png) 2 | 3 | ## Source 4 | Origin https://github.com/donwa/goindex 5 | Dark Theme & Search https://github.com/ParveenBhadooOfficial/go-drive 6 | 7 | 8 | ## Quick Deployment 9 | 1. Open https://installen.gd.workers.dev 10 | 2. Auth and get the refresh_token and paste on line 8 or just copy the full code and paste in Cloudflare workers. 11 | 3. Deploy the code to [Cloudflare Workers](https://www.cloudflare.com/workers) 12 | 13 | ![Go Drive Dark Theme](https://raw.githubusercontent.com/kulokenci/goindex-drive/master/ss.jpg) 14 | 15 | ## Use your own credentials and data 16 | * Open https://console.developers.google.com/apis/credentials 17 | * After creating project or if you already have one. 18 | * Click create credentials. 19 | * Select OAuth client ID. 20 | * Select Web application. 21 | * Give it a name. (anything for your own reference) 22 | * In Authorized JavaScript origins add https://developers.google.com 23 | * In Authorized redirect URIs add https://developers.google.com/oauthplayground 24 | * Save and note down your Client ID and Secret 25 | * Open https://developers.google.com/oauthplayground 26 | * On Right Top Side click on Setting Icon ![](https://developers.google.com/oauthplayground/assets/images/settings.png) 27 | * Click on Use your own OAuth credentials. 28 | * Enter OAuth Client ID: and OAuth Client secret: 29 | * Now back to same page https://developers.google.com/oauthplayground left side Step 1 i.e. Select & authorize APIs 30 | * Find Drive API v3 31 | * Select First Option i.e. https://www.googleapis.com/auth/drive 32 | * Click on Authorize API. and give permissions using your google account. 33 | * It will turn to Step 2 Exchange authorization code for tokens at the end of authentication. 34 | * Click on Exchange authorization code for tokens, if it goes to step 3, click on Step 2 yourself. 35 | * Select the option Auto-refresh the token before it expires. 36 | * Copy the refresh token and paste in Line 8 of https://github.com/kulokenci/goindex-drive/blob/master/worker.js along with your own Client ID and Secret at Line 6 and Line 7. 37 | * Copy the Code and paste it into https://workers.cloudflare.com Site. 38 | 39 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | // Edited by Kulo Kenci 2 | // Head 3 | document.write(''); 4 | document.write(''); 5 | // Markdown 6 | document.write(''); 7 | document.write(''); 8 | // Initialization page,And load the necessary resources 9 | function init() { 10 | document.siteName = $('title').html(); 11 | $('body').addClass("mdui-theme-primary-blue-grey mdui-theme-accent-blue"); 12 | var html = ` 13 | 14 |
15 | 17 |
18 |
19 |
20 | `; 21 | $('body').html(html); 22 | } 23 | 24 | function render(path) { 25 | if (path.indexOf("?") > 0) { 26 | path = path.substr(0, path.indexOf("?")); 27 | } 28 | title(path); 29 | nav(path); 30 | if (path.substr(-1) == '/') { 31 | list(path); 32 | } else { 33 | file(path); 34 | } 35 | } 36 | // Rendering title 37 | function title(path) { 38 | path = decodeURI(path); 39 | $('title').html(document.siteName + ' - ' + path); 40 | } 41 | // Render navigation bar 42 | function nav(path) { 43 | var html = ""; 44 | html += `${document.siteName}`; 45 | var arr = path.trim('/').split('/'); 46 | var p = '/'; 47 | if (arr.length > 0) { 48 | for (i in arr) { 49 | var n = arr[i]; 50 | n = decodeURI(n); 51 | p += n + '/'; 52 | if (n == '') { 53 | break; 54 | } 55 | html += `chevron_right${n}`; 56 | } 57 | } 58 | html += `
59 | 60 | 61 | 67 | 68 | `; 69 | $('#nav').html(html); 70 | } 71 | // Render file list 72 | function list(path) { 73 | var content = ` 74 | 75 | 76 |
77 | 90 |
91 |
92 | 94 |
95 | 96 | `; 97 | $('#content').html(content); 98 | var password = localStorage.getItem('password' + path); 99 | $('#list').html(`
`); 100 | $('#readme_md').hide().html(''); 101 | $('#head_md').hide().html(''); 102 | $.post(path, '{"password":"' + password + '"}', function (data, status) { 103 | var obj = jQuery.parseJSON(data); 104 | if (typeof obj != 'null' && obj.hasOwnProperty('error') && obj.error.code == '401') { 105 | var pass = prompt("Folder terenkripsi,Tolong masukan password", ""); 106 | localStorage.setItem('password' + path, pass); 107 | if (pass != null && pass != "") { 108 | list(path); 109 | } else { 110 | history.go(-1); 111 | } 112 | } else if (typeof obj != 'null') { 113 | list_files(path, obj.files); 114 | } 115 | }); 116 | } 117 | 118 | function list_files(path, files) { 119 | html = ""; 120 | for (i in files) { 121 | var item = files[i]; 122 | var p = path + item.name + '/'; 123 | if (item['size'] == undefined) { 124 | item['size'] = ""; 125 | } 126 | item['modifiedTime'] = utc2beijing(item['modifiedTime']); 127 | item['size'] = formatFileSize(item['size']); 128 | if (item['mimeType'] == 'application/vnd.google-apps.folder') { 129 | html += `
  • 130 |
    131 | folder_open 132 | ${item.name} 133 |
    134 |
    ${item['modifiedTime']}
    135 |
    ${item['size']}
    136 |
    137 |
  • `; 138 | } else { 139 | var p = path + item.name; 140 | var c = "file"; 141 | if (item.name == "README.md") { 142 | get_file(p, item, function (data) { 143 | markdown("#readme_md", data); 144 | }); 145 | } 146 | if (item.name == "HEAD.md") { 147 | get_file(p, item, function (data) { 148 | markdown("#head_md", data); 149 | }); 150 | } 151 | var ext = p.split('.').pop(); 152 | if ("|html|php|css|go|java|js|json|txt|sh|md|mp4|bmp|jpg|jpeg|png|gif|".indexOf(`|${ext}|`) >= 0) { 153 | p += "?a=view"; 154 | c += " view"; 155 | } 156 | html += `
  • 157 |
    158 | insert_drive_file 159 | ${item.name} 160 |
    161 |
    ${item['modifiedTime']}
    162 |
    ${item['size']}
    163 |
    164 |
  • `; 165 | } 166 | } 167 | $('#list').html(html); 168 | } 169 | 170 | function get_file(path, file, callback) { 171 | var key = "file_path_" + path + file['modifiedTime']; 172 | var data = localStorage.getItem(key); 173 | if (data != undefined) { 174 | return callback(data); 175 | } else { 176 | $.get(path, function (d) { 177 | localStorage.setItem(key, d); 178 | callback(d); 179 | }); 180 | } 181 | } 182 | // Document display ?a=view 183 | function file(path) { 184 | var name = path.split('/').pop(); 185 | var ext = name.split('.').pop().toLowerCase().replace(`?a=view`, ""); 186 | if ("|html|php|css|go|java|js|json|txt|sh|md|".indexOf(`|${ext}|`) >= 0) { 187 | return file_code(path); 188 | } 189 | if ("|mp4|".indexOf(`|${ext}|`) >= 0) { 190 | return file_video(path); 191 | } 192 | if ("|bmp|jpg|jpeg|png|gif|".indexOf(`|${ext}|`) >= 0) { 193 | return file_image(path); 194 | } 195 | } 196 | // Document display |html|php|css|go|java|js|json|txt|sh|md| 197 | function file_code(path) { 198 | var type = { 199 | "html": "html", 200 | "php": "php", 201 | "css": "css", 202 | "go": "golang", 203 | "java": "java", 204 | "js": "javascript", 205 | "json": "json", 206 | "txt": "Text", 207 | "sh": "sh", 208 | "md": "Markdown", 209 | }; 210 | var name = path.split('/').pop(); 211 | var ext = name.split('.').pop(); 212 | var href = window.location.origin + path; 213 | var content = ` 214 |
    215 |
    
    216 | 
    217 |
    218 | 219 | 220 |
    221 | file_download 222 | 223 | 224 | 225 | `; 226 | $('#content').html(content); 227 | $.get(path, function (data) { 228 | $('#editor').html($('
    ').text(data).html()); 229 | var code_type = "Text"; 230 | if (type[ext] != undefined) { 231 | code_type = type[ext]; 232 | } 233 | var editor = ace.edit("editor"); 234 | editor.setTheme("ace/theme/ambiance"); 235 | editor.setFontSize(18); 236 | editor.session.setMode("ace/mode/" + code_type); 237 | //Autocompletion 238 | editor.setOptions({ 239 | enableBasicAutocompletion: true, 240 | enableSnippets: true, 241 | enableLiveAutocompletion: true, 242 | maxLines: Infinity 243 | }); 244 | }); 245 | } 246 | // Document display mp4 247 | function file_video(path) { 248 | var url = window.location.origin + path; 249 | var content = ` 250 |
    251 |
    252 | 255 |
    256 | 257 |
    258 | 259 | 260 |
    261 |
    262 | 263 | 264 |
    265 |
    266 | file_download 267 | `; 268 | $('#content').html(content); 269 | } 270 | // 271 | function file_image(path) { 272 | var url = window.location.origin + path; 273 | var content = ` 274 |
    275 |
    276 | 277 |
    278 |
    279 | 280 | 281 |
    282 |
    283 | 284 | 285 |
    286 |
    287 | 288 | 289 |
    290 |
    291 |
    292 | file_download 293 | `; 294 | $('#content').html(content); 295 | } 296 | //Time conversion 297 | function utc2beijing(utc_datetime) { 298 | // 转为正常的时间格式 年-月-日 时:分:秒 299 | var T_pos = utc_datetime.indexOf('T'); 300 | var Z_pos = utc_datetime.indexOf('Z'); 301 | var year_month_day = utc_datetime.substr(0, T_pos); 302 | var hour_minute_second = utc_datetime.substr(T_pos + 1, Z_pos - T_pos - 1); 303 | var new_datetime = year_month_day + " " + hour_minute_second; // 2017-03-31 08:02:06 304 | // Processing becomes a timestamp 305 | timestamp = new Date(Date.parse(new_datetime)); 306 | timestamp = timestamp.getTime(); 307 | timestamp = timestamp / 1000; 308 | // Increase 8 hours,Beijing time has eight time zones than utc time 309 | var unixtimestamp = timestamp + 5.5 * 60 * 60; 310 | // Timestamp is converted to time 311 | var unixtimestamp = new Date(unixtimestamp * 1000); 312 | var year = 1900 + unixtimestamp.getYear(); 313 | var month = "0" + (unixtimestamp.getMonth() + 1); 314 | var date = "0" + unixtimestamp.getDate(); 315 | var hour = "0" + unixtimestamp.getHours(); 316 | var minute = "0" + unixtimestamp.getMinutes(); 317 | var second = "0" + unixtimestamp.getSeconds(); 318 | return year + "-" + month.substring(month.length - 2, month.length) + "-" + date.substring(date.length - 2, date.length) + " " + hour.substring(hour.length - 2, hour.length) + ":" + minute.substring(minute.length - 2, minute.length) + ":" + second.substring(second.length - 2, second.length); 319 | } 320 | // Bytes adaptive conversion to KB,MB,GB 321 | function formatFileSize(bytes) { 322 | if (bytes >= 1000000000) { 323 | bytes = (bytes / 1000000000).toFixed(2) + ' GB'; 324 | } else if (bytes >= 1000000) { 325 | bytes = (bytes / 1000000).toFixed(2) + ' MB'; 326 | } else if (bytes >= 1000) { 327 | bytes = (bytes / 1000).toFixed(2) + ' KB'; 328 | } else if (bytes > 1) { 329 | bytes = bytes + ' bytes'; 330 | } else if (bytes == 1) { 331 | bytes = bytes + ' byte'; 332 | } else { 333 | bytes = ''; 334 | } 335 | return bytes; 336 | } 337 | String.prototype.trim = function (char) { 338 | if (char) { 339 | return this.replace(new RegExp('^\\' + char + '+|\\' + char + '+$', 'g'), ''); 340 | } 341 | return this.replace(/^\s+|\s+$/g, ''); 342 | }; 343 | // README.md HEAD.md stand by 344 | function markdown(el, data) { 345 | if (window.md == undefined) { 346 | //$.getScript('https://cdn.jsdelivr.net/npm/markdown-it@9.1.0/dist/markdown-it.min.js',function(){ 347 | window.md = window.markdownit(); 348 | markdown(el, data); 349 | //}); 350 | } else { 351 | var html = md.render(data); 352 | $(el).show().html(html); 353 | } 354 | } 355 | document.write(''); 356 | // Listening back event 357 | window.onpopstate = function () { 358 | var path = window.location.pathname; 359 | render(path); 360 | } 361 | $(function () { 362 | init(); 363 | var path = window.location.pathname; 364 | $("body").on("click", '.folder', function () { 365 | var url = $(this).attr('href'); 366 | history.pushState(null, null, url); 367 | render(url); 368 | return false; 369 | }); 370 | $("body").on("click", '.view', function () { 371 | var url = $(this).attr('href'); 372 | history.pushState(null, null, url); 373 | render(url); 374 | return false; 375 | }); 376 | render(path); 377 | }); 378 | //# sourceMappingURL=/sm/7de5ebd04c9d149c688ff531decdeb96216884e2f3038bf5009b329a0c6f8140.map 379 | -------------------------------------------------------------------------------- /cari.js: -------------------------------------------------------------------------------- 1 | function myFunction() { 2 | var e, t, n, l; 3 | for (e = document.getElementById("myInput").value.toUpperCase(), t = document.getElementById("list").getElementsByTagName("li"), l = 0; l < t.length; l++)((n = t[l].getElementsByTagName("a")[0]).textContent || n.innerText).toUpperCase().indexOf(e) > -1 ? t[l].style.display = "" : t[l].style.display = "none" 4 | } 5 | -------------------------------------------------------------------------------- /cari.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lsmother/goindex-drive/39421f996f49c7eaaba4088687a867fb1f715627/cari.png -------------------------------------------------------------------------------- /custom.css: -------------------------------------------------------------------------------- 1 | .mdui-theme-primary-blue-grey .mdui-color-theme { 2 | background-color: #232427!important 3 | } 4 | body { 5 | color: rgba(255, 255, 255, .87); 6 | background-color: #333232 7 | } 8 | * { 9 | box-sizing: border-box 10 | } 11 | #myInput { 12 | background-image: url(https://cdn.jsdelivr.net/gh/kulokenci/goindex-drive@2.0/cari.png); 13 | background-position: 10px 12px; 14 | background-repeat: no-repeat; 15 | width: 100%; 16 | font-size: 16px; 17 | padding: 12px 20px 12px 40px; 18 | border: 1px solid #ddd; 19 | margin-bottom: 12px 20 | } 21 | #myUL { 22 | list-style-type: none; 23 | padding: 0; 24 | margin: 0 25 | } 26 | #myUL li a { 27 | border: 1px solid #ddd; 28 | margin-top: -1px; 29 | background-color: #f6f6f6; 30 | padding: 12px; 31 | text-decoration: none; 32 | font-size: 18px; 33 | color: #000; 34 | display: block 35 | } 36 | #myUL li a:hover:not(.header) { 37 | background-color: #eee 38 | } 39 | -------------------------------------------------------------------------------- /go-drive-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lsmother/goindex-drive/39421f996f49c7eaaba4088687a867fb1f715627/go-drive-logo.png -------------------------------------------------------------------------------- /ss.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lsmother/goindex-drive/39421f996f49c7eaaba4088687a867fb1f715627/ss.jpg -------------------------------------------------------------------------------- /worker.js: -------------------------------------------------------------------------------- 1 | var authConfig = { 2 | "siteName": "Google Drive", // Site Name 3 | "root_pass": "", // Root Password 4 | "version": "2.0", // Site Version 5 | "theme": "material", // material classic 6 | "client_id": "202264815644.apps.googleusercontent.com", // Google Client ID 7 | "client_secret": "X4Z3ca8xfWDb1Voo-F9a7ZxJ", // Google Client Secret 8 | "refresh_token": "", // Refresh token "root": "root" // Root directory 9 | "root": "root" // Root directory 10 | }; 11 | 12 | var gd; 13 | 14 | var html = ` 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | ${authConfig.siteName} 23 | 24 | 25 | 26 | 27 | 28 | 29 | `; 30 | 31 | addEventListener('fetch', event => { 32 | event.respondWith(handleRequest(event.request)); 33 | }); 34 | 35 | /** 36 | * Fetch and log a request 37 | * @param {Request} request 38 | */ 39 | async function handleRequest(request) { 40 | if(gd == undefined){ 41 | gd = new googleDrive(authConfig); 42 | } 43 | 44 | if(request.method == 'POST'){ 45 | return apiRequest(request); 46 | } 47 | 48 | let url = new URL(request.url); 49 | let path = url.pathname; 50 | let action = url.searchParams.get('a'); 51 | 52 | if(path.substr(-1) == '/' || action != null){ 53 | return new Response(html,{status:200,headers:{'Content-Type':'text/html; charset=utf-8'}}); 54 | }else{ 55 | if(path.split('/').pop().toLowerCase() == ".password"){ 56 | return new Response("",{status:404}); 57 | } 58 | let file = await gd.file(path); 59 | let range = request.headers.get('Range'); 60 | return gd.down(file.id, range); 61 | } 62 | } 63 | 64 | 65 | async function apiRequest(request) { 66 | let url = new URL(request.url); 67 | let path = url.pathname; 68 | 69 | let option = {status:200,headers:{'Access-Control-Allow-Origin':'*'}} 70 | 71 | if(path.substr(-1) == '/'){ 72 | // check password 73 | let password = await gd.password(path); 74 | console.log("dir password", password); 75 | if(password != undefined && password != null && password != ""){ 76 | try{ 77 | var obj = await request.json(); 78 | }catch(e){ 79 | var obj = {}; 80 | } 81 | console.log(password,obj); 82 | if(password != obj.password){ 83 | let html = `{"error": {"code": 401,"message": "password error."}}`; 84 | return new Response(html,option); 85 | } 86 | } 87 | let list = await gd.list(path); 88 | return new Response(JSON.stringify(list),option); 89 | }else{ 90 | let file = await gd.file(path); 91 | let range = request.headers.get('Range'); 92 | return new Response(JSON.stringify(file)); 93 | } 94 | } 95 | 96 | class googleDrive { 97 | constructor(authConfig) { 98 | this.authConfig = authConfig; 99 | this.paths = []; 100 | this.files = []; 101 | this.passwords = []; 102 | this.paths["/"] = authConfig.root; 103 | if(authConfig.root_pass != ""){ 104 | this.passwords["/"] = authConfig.root_pass; 105 | } 106 | this.accessToken(); 107 | } 108 | 109 | async down(id, range=''){ 110 | let url = `https://www.googleapis.com/drive/v3/files/${id}?alt=media`; 111 | let requestOption = await this.requestOption(); 112 | requestOption.headers['Range'] = range; 113 | return await fetch(url, requestOption); 114 | } 115 | 116 | async file(path){ 117 | if(typeof this.files[path] == 'undefined'){ 118 | this.files[path] = await this._file(path); 119 | } 120 | return this.files[path] ; 121 | } 122 | 123 | async _file(path){ 124 | let arr = path.split('/'); 125 | let name = arr.pop(); 126 | name = decodeURIComponent(name).replace(/\'/g, "\\'"); 127 | let dir = arr.join('/')+'/'; 128 | console.log(name, dir); 129 | let parent = await this.findPathId(dir); 130 | console.log(parent); 131 | let url = 'https://www.googleapis.com/drive/v3/files'; 132 | let params = {'includeItemsFromAllDrives':true,'supportsAllDrives':true}; 133 | params.q = `'${parent}' in parents and name = '${name}' andtrashed = false`; 134 | params.fields = "files(id, name, mimeType, size ,createdTime, modifiedTime, iconLink, thumbnailLink)"; 135 | url += '?'+this.enQuery(params); 136 | let requestOption = await this.requestOption(); 137 | let response = await fetch(url, requestOption); 138 | let obj = await response.json(); 139 | console.log(obj); 140 | return obj.files[0]; 141 | } 142 | 143 | // reqeust cache 144 | async list(path){ 145 | let id = await this.findPathId(path); 146 | return this._ls(id); 147 | } 148 | 149 | async password(path){ 150 | if(this.passwords[path] !== undefined){ 151 | return this.passwords[path]; 152 | } 153 | 154 | console.log("load",path,".password",this.passwords[path]); 155 | 156 | let file = await gd.file(path+'.password'); 157 | if(file == undefined){ 158 | this.passwords[path] = null; 159 | }else{ 160 | let url = `https://www.googleapis.com/drive/v3/files/${file.id}?alt=media`; 161 | let requestOption = await this.requestOption(); 162 | let response = await this.fetch200(url, requestOption); 163 | this.passwords[path] = await response.text(); 164 | } 165 | 166 | return this.passwords[path]; 167 | } 168 | 169 | async _ls(parent){ 170 | console.log("_ls",parent); 171 | 172 | if(parent==undefined){ 173 | return null; 174 | } 175 | let url = 'https://www.googleapis.com/drive/v3/files'; 176 | let params = {'includeItemsFromAllDrives':true,'supportsAllDrives':true}; 177 | params.q = `'${parent}' in parents and trashed = false AND name !='.password'`; 178 | params.orderBy= 'folder,name,modifiedTime desc'; 179 | params.fields = "nextPageToken, files(id, name, mimeType, size , modifiedTime)"; 180 | params.pageSize = 1000; 181 | url += '?'+this.enQuery(params); 182 | let requestOption = await this.requestOption(); 183 | let response = await fetch(url, requestOption); 184 | let obj = await response.json(); 185 | return obj; 186 | } 187 | 188 | async findPathId(path){ 189 | let c_path = '/'; 190 | let c_id = this.paths[c_path]; 191 | 192 | let arr = path.trim('/').split('/'); 193 | for(let name of arr){ 194 | c_path += name+'/'; 195 | 196 | if(typeof this.paths[c_path] == 'undefined'){ 197 | let id = await this._findDirId(c_id, name); 198 | this.paths[c_path] = id; 199 | } 200 | 201 | c_id = this.paths[c_path]; 202 | if(c_id == undefined || c_id == null){ 203 | break; 204 | } 205 | } 206 | console.log(this.paths); 207 | return this.paths[path]; 208 | } 209 | 210 | async _findDirId(parent, name){ 211 | name = decodeURIComponent(name).replace(/\'/g, "\\'"); 212 | 213 | console.log("_findDirId",parent,name); 214 | 215 | if(parent==undefined){ 216 | return null; 217 | } 218 | 219 | let url = 'https://www.googleapis.com/drive/v3/files'; 220 | let params = {'includeItemsFromAllDrives':true,'supportsAllDrives':true}; 221 | params.q = `'${parent}' in parents and mimeType = 'application/vnd.google-apps.folder' and name = '${name}' and trashed = false`; 222 | params.fields = "nextPageToken, files(id, name, mimeType)"; 223 | url += '?'+this.enQuery(params); 224 | let requestOption = await this.requestOption(); 225 | let response = await fetch(url, requestOption); 226 | let obj = await response.json(); 227 | if(obj.files[0] == undefined){ 228 | return null; 229 | } 230 | return obj.files[0].id; 231 | } 232 | 233 | async accessToken(){ 234 | console.log("accessToken"); 235 | if(this.authConfig.expires == undefined ||this.authConfig.expires< Date.now()){ 236 | const obj = await this.fetchAccessToken(); 237 | if(obj.access_token != undefined){ 238 | this.authConfig.accessToken = obj.access_token; 239 | this.authConfig.expires = Date.now()+3500*1000; 240 | } 241 | } 242 | return this.authConfig.accessToken; 243 | } 244 | 245 | async fetchAccessToken() { 246 | console.log("fetchAccessToken"); 247 | const url = "https://www.googleapis.com/oauth2/v4/token"; 248 | const headers = { 249 | 'Content-Type': 'application/x-www-form-urlencoded' 250 | }; 251 | const post_data = { 252 | 'client_id': this.authConfig.client_id, 253 | 'client_secret': this.authConfig.client_secret, 254 | 'refresh_token': this.authConfig.refresh_token, 255 | 'grant_type': 'refresh_token' 256 | } 257 | 258 | let requestOption = { 259 | 'method': 'POST', 260 | 'headers': headers, 261 | 'body': this.enQuery(post_data) 262 | }; 263 | 264 | const response = await fetch(url, requestOption); 265 | return await response.json(); 266 | } 267 | 268 | async fetch200(url, requestOption) { 269 | let response; 270 | for (let i = 0; i < 3; i++) { 271 | response = await fetch(url, requestOption); 272 | console.log(response.status); 273 | if (response.status != 403) { 274 | break; 275 | } 276 | await this.sleep(800 * (i + 1)); 277 | } 278 | return response; 279 | } 280 | 281 | async requestOption(headers={},method='GET'){ 282 | const accessToken = await this.accessToken(); 283 | headers['authorization'] = 'Bearer '+ accessToken; 284 | return {'method': method, 'headers':headers}; 285 | } 286 | 287 | enQuery(data) { 288 | const ret = []; 289 | for (let d in data) { 290 | ret.push(encodeURIComponent(d) + '=' + encodeURIComponent(data[d])); 291 | } 292 | return ret.join('&'); 293 | } 294 | 295 | sleep(ms) { 296 | return new Promise(function (resolve, reject) { 297 | let i = 0; 298 | setTimeout(function () { 299 | console.log('sleep' + ms); 300 | i++; 301 | if (i >= 2) reject(new Error('i>=2')); 302 | else resolve(i); 303 | }, ms); 304 | }) 305 | } 306 | } 307 | 308 | String.prototype.trim = function (char) { 309 | if (char) { 310 | return this.replace(new RegExp('^\\'+char+'+|\\'+char+'+$', 'g'), ''); 311 | } 312 | return this.replace(/^\s+|\s+$/g, ''); 313 | }; 314 | --------------------------------------------------------------------------------