HttpRequest.ts 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /**
  2. * Http请求
  3. * @author Egret、袁浩
  4. */
  5. export class HttpRequest {
  6. private onIOError: (url: String) => void
  7. private onComplete: (httpRequest: HttpRequest) => void
  8. private onProgress: (loaded: number, total: number) => void
  9. /**
  10. * @private
  11. */
  12. public constructor(onIOError: (url: String) => void, onComplete: (data: HttpRequest) => void, onProgress: (loaded: number, total: number) => void) {
  13. this.onIOError = onIOError;
  14. this.onComplete = onComplete;
  15. this.onProgress = onProgress;
  16. }
  17. /**
  18. * @private
  19. */
  20. private _xhr: XMLHttpRequest;
  21. /**
  22. *
  23. */
  24. public timeout: number = 0;
  25. /**
  26. * @private
  27. * 本次请求返回的数据,数据类型根据responseType设置的值确定。
  28. */
  29. public get response(): any {
  30. if (!this._xhr) {
  31. return null;
  32. }
  33. if (this._xhr.response != undefined) {
  34. return this._xhr.response;
  35. }
  36. if (this._responseType == "text") {
  37. return this._xhr.responseText;
  38. }
  39. if (this._responseType == "arraybuffer" && /msie 9.0/i.test(navigator.userAgent)) {
  40. let w: any = window;
  41. return w.convertResponseBodyToText(this._xhr["responseBody"]);
  42. }
  43. if (this._responseType == "document") {
  44. return this._xhr.responseXML;
  45. }
  46. /*if (this._xhr.responseXML) {
  47. return this._xhr.responseXML;
  48. }
  49. if (this._xhr.responseText != undefined) {
  50. return this._xhr.responseText;
  51. }*/
  52. return null;
  53. }
  54. /**
  55. * @private
  56. */
  57. private _responseType: "" | "arraybuffer" | "blob" | "document" | "json" | "text";
  58. /**
  59. * @private
  60. * 设置返回的数据格式,请使用 HttpResponseType 里定义的枚举值。设置非法的值或不设置,都将使用HttpResponseType.TEXT。
  61. */
  62. public get responseType(): "" | "arraybuffer" | "blob" | "document" | "json" | "text" {
  63. return this._responseType;
  64. }
  65. public set responseType(value: "" | "arraybuffer" | "blob" | "document" | "json" | "text") {
  66. this._responseType = value;
  67. }
  68. /**
  69. * @private
  70. */
  71. private _withCredentials: boolean;
  72. /**
  73. * @private
  74. * 表明在进行跨站(cross-site)的访问控制(Access-Control)请求时,是否使用认证信息(例如cookie或授权的header)。 默认为 false。(这个标志不会影响同站的请求)
  75. */
  76. public get withCredentials(): boolean {
  77. return this._withCredentials;
  78. }
  79. public set withCredentials(value: boolean) {
  80. this._withCredentials = value;
  81. }
  82. /**
  83. * @private
  84. */
  85. private _url: string = "";
  86. public get url(): string {
  87. return this._url;
  88. }
  89. private _method: string = "";
  90. /**
  91. * @private
  92. *
  93. * @returns
  94. */
  95. private getXHR(): XMLHttpRequest {
  96. if (window["XMLHttpRequest"]) {
  97. return new window["XMLHttpRequest"]();
  98. } else {
  99. return new ActiveXObject("MSXML2.XMLHTTP");
  100. }
  101. }
  102. /**
  103. * @private
  104. * 初始化一个请求.注意,若在已经发出请求的对象上调用此方法,相当于立即调用abort().
  105. * @param url 该请求所要访问的URL该请求所要访问的URL
  106. * @param method 请求所使用的HTTP方法, 请使用 HttpMethod 定义的枚举值.
  107. */
  108. public open(url: string, method: string = "GET"): void {
  109. this._url = url;
  110. this._method = method;
  111. if (this._xhr) {
  112. this._xhr.abort();
  113. this._xhr = null;
  114. }
  115. let xhr = this.getXHR();//new XMLHttpRequest();
  116. if (window["XMLHttpRequest"]) {
  117. xhr.addEventListener("load", this.onload.bind(this));
  118. xhr.addEventListener("error", this.onerror.bind(this));
  119. } else {
  120. xhr.onreadystatechange = this.onReadyStateChange.bind(this);
  121. }
  122. xhr.onprogress = this.updateProgress.bind(this);
  123. xhr.ontimeout = this.onTimeout.bind(this)
  124. xhr.open(this._method, this._url, true);
  125. this._xhr = xhr;
  126. }
  127. /**
  128. * @private
  129. * 发送请求.
  130. * @param data 需要发送的数据
  131. */
  132. public send(data?: any): void {
  133. if (this._responseType != null) {
  134. this._xhr.responseType = this._responseType;
  135. }
  136. if (this._withCredentials != null) {
  137. this._xhr.withCredentials = this._withCredentials;
  138. }
  139. if (this.headerObj) {
  140. for (let key in this.headerObj) {
  141. this._xhr.setRequestHeader(key, this.headerObj[key]);
  142. }
  143. }
  144. this._xhr.timeout = this.timeout;
  145. this._xhr.send(data);
  146. }
  147. /**
  148. * @private
  149. * 如果请求已经被发送,则立刻中止请求.
  150. */
  151. public abort(): void {
  152. if (this._xhr) {
  153. this._xhr.abort();
  154. }
  155. }
  156. /**
  157. * @private
  158. * 返回所有响应头信息(响应头名和值), 如果响应头还没接受,则返回"".
  159. */
  160. public getAllResponseHeaders(): string {
  161. if (!this._xhr) {
  162. return null;
  163. }
  164. let result = this._xhr.getAllResponseHeaders();
  165. return result ? result : "";
  166. }
  167. private headerObj: any;
  168. /**
  169. * @private
  170. * 给指定的HTTP请求头赋值.在这之前,您必须确认已经调用 open() 方法打开了一个url.
  171. * @param header 将要被赋值的请求头名称.
  172. * @param value 给指定的请求头赋的值.
  173. */
  174. public setRequestHeader(header: string, value: string): void {
  175. if (!this.headerObj) {
  176. this.headerObj = {};
  177. }
  178. this.headerObj[header] = value;
  179. }
  180. /**
  181. * @private
  182. * 返回指定的响应头的值, 如果响应头还没被接受,或该响应头不存在,则返回"".
  183. * @param header 要返回的响应头名称
  184. */
  185. public getResponseHeader(header: string): string {
  186. if (!this._xhr) {
  187. return null;
  188. }
  189. let result = this._xhr.getResponseHeader(header);
  190. return result ? result : "";
  191. }
  192. /**
  193. * @private
  194. */
  195. private onTimeout(): void {
  196. this.onIOError && this.onIOError(this.url);
  197. }
  198. /**
  199. * @private
  200. */
  201. private onReadyStateChange(): void {
  202. let xhr = this._xhr;
  203. if (xhr.readyState == 4) {// 4 = "loaded"
  204. let ioError = (xhr.status >= 400 || xhr.status == 0);
  205. let url = this._url;
  206. let self = this;
  207. window.setTimeout(function (): void {
  208. if (ioError) {//请求错误
  209. self.onIOError && self.onIOError(self.url);
  210. }
  211. else {
  212. self.onComplete && self.onComplete(self);
  213. }
  214. }, 0)
  215. }
  216. }
  217. /**
  218. * @private
  219. */
  220. private updateProgress(event): void {
  221. if (event.lengthComputable) {
  222. this.onProgress && this.onProgress(event.loaded, event.total);
  223. }
  224. }
  225. /**
  226. * @private
  227. */
  228. private onload(): void {
  229. let self = this;
  230. let xhr = this._xhr;
  231. let url = this._url;
  232. let ioError = (xhr.status >= 400);
  233. window.setTimeout(function (): void {
  234. if (ioError) {//请求错误
  235. self.onIOError && self.onIOError(self.url);
  236. }
  237. else {
  238. self.onComplete && self.onComplete(self);
  239. }
  240. }, 0);
  241. }
  242. /**
  243. * @private
  244. */
  245. private onerror(): void {
  246. let url = this._url;
  247. let self = this;
  248. window.setTimeout(function (): void {
  249. self.onIOError && self.onIOError(self.url);
  250. }, 0);
  251. }
  252. }