Няма описание

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. import RNFetchBlob from '../index.js'
  2. import Log from '../utils/log.js'
  3. import fs from '../fs'
  4. import unicode from '../utils/unicode'
  5. import Blob from './Blob'
  6. const log = new Log('FetchPolyfill')
  7. log.disable()
  8. // log.level(3)
  9. export default class Fetch {
  10. constructor(config:RNFetchBlobConfig) {
  11. Object.assign(this, new RNFetchBlobFetchPolyfill(config))
  12. }
  13. }
  14. class RNFetchBlobFetchPolyfill {
  15. constructor(config:RNFetchBlobConfig) {
  16. this.build = () => (url, options = {}) => {
  17. let body = options.body
  18. let promise = Promise.resolve()
  19. let blobCache = null
  20. options.headers = options.headers || {}
  21. let ctype = options['Content-Type'] || options['content-type']
  22. let ctypeH = options.headers['Content-Type'] || options.headers['content-type']
  23. options.headers['Content-Type'] = ctype || ctypeH
  24. options.headers['content-type'] = ctype || ctypeH
  25. options.method = options.method || 'GET'
  26. if(body) {
  27. // When the request body is an instance of FormData, create a Blob cache
  28. // to upload the body.
  29. if(body instanceof FormData) {
  30. log.verbose('convert FormData to blob body')
  31. promise = Blob.build(body).then((b) => {
  32. blobCache = b
  33. options.headers['Content-Type'] = 'multipart/form-data;boundary=' + b.multipartBoundary
  34. return Promise.resolve(RNFetchBlob.wrap(b._ref))
  35. })
  36. }
  37. // When request body is a Blob, use file URI of the Blob as request body.
  38. else if (body.isRNFetchBlobPolyfill)
  39. promise = Promise.resolve(RNFetchBlob.wrap(body.blobPath))
  40. // send it as-is, leave the native module decide how to send the body.
  41. else
  42. promise = Promise.resolve(body)
  43. }
  44. // task is a progress reportable and cancellable Promise, however,
  45. // task.then is not, so we have to extend task.then with progress and
  46. // cancel function
  47. let task = promise
  48. .then((body) => {
  49. return RNFetchBlob.config(config)
  50. .fetch(options.method, url, options.headers, body)
  51. })
  52. let statefulPromise = task.then((resp) => {
  53. log.verbose('response', resp)
  54. // release blob cache created when sending request
  55. if(blobCache !== null && blobCache instanceof Blob)
  56. blobCache.close()
  57. return Promise.resolve(new RNFetchBlobFetchRepsonse(resp))
  58. })
  59. // extend task.then progress with report and cancelling functions
  60. statefulPromise.cancel = task.cancel
  61. statefulPromise.progress = task.progress
  62. statefulPromise.uploadProgress = task.uploadProgress
  63. return statefulPromise
  64. }
  65. }
  66. }
  67. class RNFetchBlobFetchRepsonse {
  68. constructor(resp:FetchBlobResponse) {
  69. let info = resp.info()
  70. this.headers = info.headers
  71. this.ok = info.status >= 200 && info.status <= 299,
  72. this.status = info.status
  73. this.type = 'basic'
  74. this.bodyUsed = false
  75. this.resp = resp
  76. this.rnfbRespInfo = info
  77. this.rnfbResp = resp
  78. }
  79. arrayBuffer(){
  80. log.verbose('to arrayBuffer', this.rnfbRespInfo)
  81. return readArrayBuffer(this.rnfbResp, this.rnfbRespInfo)
  82. }
  83. text() {
  84. log.verbose('to text', this.rnfbResp, this.rnfbRespInfo)
  85. return readText(this.rnfbResp, this.rnfbRespInfo)
  86. }
  87. json() {
  88. log.verbose('to json', this.rnfbResp, this.rnfbRespInfo)
  89. return readJSON(this.rnfbResp, this.rnfbRespInfo)
  90. }
  91. formData() {
  92. log.verbose('to formData', this.rnfbResp, this.rnfbRespInfo)
  93. return readFormData(this.rnfbResp, this.rnfbRespInfo)
  94. }
  95. blob() {
  96. log.verbose('to blob', this.rnfbResp, this.rnfbRespInfo)
  97. return readBlob(this.rnfbResp, this.rnfbRespInfo)
  98. }
  99. }
  100. /**
  101. * Get response data as string.
  102. * @param {FetchBlobResponse} resp Response data object from RNFB fetch call.
  103. * @param {RNFetchBlobResponseInfo} info Response informations.
  104. * @return {Promise<string>}
  105. */
  106. function readText(resp, info):Promise<string> {
  107. switch (info.rnfbEncode) {
  108. case 'base64':
  109. return Promise.resolve(resp.text())
  110. break
  111. case 'path':
  112. return resp.readFile('utf8').then((data) => {
  113. return Promise.resolve(data)
  114. })
  115. break
  116. default:
  117. return Promise.resolve(resp.text())
  118. break
  119. }
  120. }
  121. /**
  122. * Get response data as RNFetchBlob Blob polyfill object.
  123. * @param {FetchBlobResponse} resp Response data object from RNFB fetch call.
  124. * @param {RNFetchBlobResponseInfo} info Response informations.
  125. * @return {Promise<Blob>}
  126. */
  127. function readBlob(resp, info):Promise<Blob> {
  128. log.verbose('readBlob', resp, info)
  129. let cType = info.headers['Content-Type']
  130. switch (info.rnfbEncode) {
  131. case 'base64':
  132. return Blob.build(resp.data, { type : `${cType};BASE64` })
  133. case 'path':
  134. return Blob.build(RNFetchBlob.wrap(resp.data), { type : `${cType}`})
  135. default:
  136. return Blob.build(resp.data, { type : `${cType}`})
  137. }
  138. }
  139. /**
  140. * Get response data as JSON object.
  141. * @param {FetchBlobResponse} resp Response data object from RNFB fetch call.
  142. * @param {RNFetchBlobResponseInfo} info Response informations.
  143. * @return {Promise<object>}
  144. */
  145. function readJSON(resp, info):Promise<object> {
  146. log.verbose('readJSON', resp, info)
  147. switch (info.rnfbEncode) {
  148. case 'base64':
  149. return Promise.resolve(resp.json())
  150. case 'path':
  151. return resp.readFile('utf8').then((data) => {
  152. return Promise.resolve(JSON.parse(data))
  153. })
  154. default:
  155. return Promise.resolve(JSON.parse(resp.data))
  156. }
  157. }