requests.js 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import { includes, encodeBody } from './helpers';
  2. import bridge from './bridge';
  3. const map = {};
  4. const queue = [];
  5. export function onRequestCreate(details) {
  6. const req = {
  7. details,
  8. req: {
  9. abort: reqAbort,
  10. },
  11. };
  12. details.url = getFullUrl(details.url);
  13. queue.push(req);
  14. bridge.post({ cmd: 'GetRequestId' });
  15. return req.req;
  16. }
  17. export function onRequestStart(id) {
  18. const req = queue.shift();
  19. start(req, id);
  20. }
  21. export function onRequestCallback(res) {
  22. const req = map[res.id];
  23. if (req) callback(req, res);
  24. }
  25. function reqAbort() {
  26. bridge.post({ cmd: 'AbortRequest', data: this.id });
  27. }
  28. function parseData(req, details) {
  29. if (req.resType) {
  30. // blob or arraybuffer
  31. let data = req.data.response.split(',');
  32. const mimetype = data[0].match(/^data:(.*?);base64$/);
  33. if (!mimetype) {
  34. // invalid
  35. req.data.response = null;
  36. } else {
  37. data = window.atob(data[1]);
  38. const arr = new window.Uint8Array(data.length);
  39. for (let i = 0; i < data.length; i += 1) arr[i] = data.charCodeAt(i);
  40. if (details.responseType === 'blob') {
  41. // blob
  42. return new Blob([arr], { type: mimetype });
  43. }
  44. // arraybuffer
  45. return arr.buffer;
  46. }
  47. } else if (details.responseType === 'json') {
  48. // json
  49. return JSON.parse(req.data.response);
  50. } else {
  51. // text
  52. return req.data.response;
  53. }
  54. }
  55. // request object functions
  56. function callback(req, res) {
  57. const cb = req.details[`on${res.type}`];
  58. if (cb) {
  59. if (res.data.response) {
  60. if (!req.data) req.data = [parseData(res, req.details)];
  61. res.data.response = req.data[0];
  62. }
  63. res.data.context = req.details.context;
  64. cb(res.data);
  65. }
  66. if (res.type === 'loadend') delete map[req.id];
  67. }
  68. function start(req, id) {
  69. const { details } = req;
  70. const payload = {
  71. id,
  72. method: details.method,
  73. url: details.url,
  74. user: details.user,
  75. password: details.password,
  76. headers: details.headers,
  77. overrideMimeType: details.overrideMimeType,
  78. };
  79. req.id = id;
  80. map[id] = req;
  81. if (includes(['arraybuffer', 'blob'], details.responseType)) {
  82. payload.responseType = 'blob';
  83. }
  84. encodeBody(details.data)
  85. .then(body => {
  86. payload.data = body;
  87. bridge.post({
  88. cmd: 'HttpRequest',
  89. data: payload,
  90. });
  91. });
  92. }
  93. function getFullUrl(url) {
  94. const a = document.createElement('a');
  95. a.setAttribute('href', url);
  96. return a.href;
  97. }