* HTTP GET 请求,返回文本内容
(url: string)
| 419 | * HTTP GET 请求,返回文本内容 |
| 420 | */ |
| 421 | private httpGet(url: string): Promise<string> { |
| 422 | return new Promise((resolve, reject) => { |
| 423 | const request = net.request(url) |
| 424 | let data = '' |
| 425 | let resolved = false |
| 426 | const fail = (error: Error): void => { |
| 427 | clearTimeout(timeout) |
| 428 | if (!resolved) { |
| 429 | resolved = true |
| 430 | reject(error) |
| 431 | } |
| 432 | } |
| 433 | const done = (value: string): void => { |
| 434 | clearTimeout(timeout) |
| 435 | if (!resolved) { |
| 436 | resolved = true |
| 437 | resolve(value) |
| 438 | } |
| 439 | } |
| 440 | |
| 441 | const timeout = setTimeout(() => { |
| 442 | if (!resolved) { |
| 443 | resolved = true |
| 444 | request.abort() |
| 445 | reject(new Error('请求超时')) |
| 446 | } |
| 447 | }, 10000) |
| 448 | |
| 449 | request.on('response', (response) => { |
| 450 | response.on('error', fail) |
| 451 | |
| 452 | // 处理重定向 |
| 453 | if ( |
| 454 | response.statusCode && |
| 455 | response.statusCode >= 300 && |
| 456 | response.statusCode < 400 && |
| 457 | response.headers.location |
| 458 | ) { |
| 459 | clearTimeout(timeout) |
| 460 | resolved = true |
| 461 | const location = Array.isArray(response.headers.location) |
| 462 | ? response.headers.location[0] |
| 463 | : response.headers.location |
| 464 | this.httpGet(location).then(resolve).catch(reject) |
| 465 | return |
| 466 | } |
| 467 | |
| 468 | response.on('data', (chunk) => { |
| 469 | data += chunk.toString() |
| 470 | // 只读取前 100KB,足够解析 head 中的 favicon |
| 471 | if (data.length > 100 * 1024) { |
| 472 | request.abort() |
| 473 | done(data) |
| 474 | } |
| 475 | }) |
| 476 | response.on('end', () => { |
| 477 | done(data) |
| 478 | }) |