blob: 4a31171aca113c0c629248f0fe14fdd26eebb8e3 [file] [log] [blame]
Copybara botbe50d492023-11-30 00:16:42 +01001define( [
2 "../core",
3 "../var/support",
4 "../ajax"
5], function( jQuery, support ) {
6
7"use strict";
8
9jQuery.ajaxSettings.xhr = function() {
10 try {
11 return new window.XMLHttpRequest();
12 } catch ( e ) {}
13};
14
15var xhrSuccessStatus = {
16
17 // File protocol always yields status code 0, assume 200
18 0: 200,
19
20 // Support: IE <=9 only
21 // #1450: sometimes IE returns 1223 when it should be 204
22 1223: 204
23 },
24 xhrSupported = jQuery.ajaxSettings.xhr();
25
26support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
27support.ajax = xhrSupported = !!xhrSupported;
28
29jQuery.ajaxTransport( function( options ) {
30 var callback, errorCallback;
31
32 // Cross domain only allowed if supported through XMLHttpRequest
33 if ( support.cors || xhrSupported && !options.crossDomain ) {
34 return {
35 send: function( headers, complete ) {
36 var i,
37 xhr = options.xhr();
38
39 xhr.open(
40 options.type,
41 options.url,
42 options.async,
43 options.username,
44 options.password
45 );
46
47 // Apply custom fields if provided
48 if ( options.xhrFields ) {
49 for ( i in options.xhrFields ) {
50 xhr[ i ] = options.xhrFields[ i ];
51 }
52 }
53
54 // Override mime type if needed
55 if ( options.mimeType && xhr.overrideMimeType ) {
56 xhr.overrideMimeType( options.mimeType );
57 }
58
59 // X-Requested-With header
60 // For cross-domain requests, seeing as conditions for a preflight are
61 // akin to a jigsaw puzzle, we simply never set it to be sure.
62 // (it can always be set on a per-request basis or even using ajaxSetup)
63 // For same-domain requests, won't change header if already provided.
64 if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
65 headers[ "X-Requested-With" ] = "XMLHttpRequest";
66 }
67
68 // Set headers
69 for ( i in headers ) {
70 xhr.setRequestHeader( i, headers[ i ] );
71 }
72
73 // Callback
74 callback = function( type ) {
75 return function() {
76 if ( callback ) {
77 callback = errorCallback = xhr.onload =
78 xhr.onerror = xhr.onabort = xhr.ontimeout =
79 xhr.onreadystatechange = null;
80
81 if ( type === "abort" ) {
82 xhr.abort();
83 } else if ( type === "error" ) {
84
85 // Support: IE <=9 only
86 // On a manual native abort, IE9 throws
87 // errors on any property access that is not readyState
88 if ( typeof xhr.status !== "number" ) {
89 complete( 0, "error" );
90 } else {
91 complete(
92
93 // File: protocol always yields status 0; see #8605, #14207
94 xhr.status,
95 xhr.statusText
96 );
97 }
98 } else {
99 complete(
100 xhrSuccessStatus[ xhr.status ] || xhr.status,
101 xhr.statusText,
102
103 // Support: IE <=9 only
104 // IE9 has no XHR2 but throws on binary (trac-11426)
105 // For XHR2 non-text, let the caller handle it (gh-2498)
106 ( xhr.responseType || "text" ) !== "text" ||
107 typeof xhr.responseText !== "string" ?
108 { binary: xhr.response } :
109 { text: xhr.responseText },
110 xhr.getAllResponseHeaders()
111 );
112 }
113 }
114 };
115 };
116
117 // Listen to events
118 xhr.onload = callback();
119 errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" );
120
121 // Support: IE 9 only
122 // Use onreadystatechange to replace onabort
123 // to handle uncaught aborts
124 if ( xhr.onabort !== undefined ) {
125 xhr.onabort = errorCallback;
126 } else {
127 xhr.onreadystatechange = function() {
128
129 // Check readyState before timeout as it changes
130 if ( xhr.readyState === 4 ) {
131
132 // Allow onerror to be called first,
133 // but that will not handle a native abort
134 // Also, save errorCallback to a variable
135 // as xhr.onerror cannot be accessed
136 window.setTimeout( function() {
137 if ( callback ) {
138 errorCallback();
139 }
140 } );
141 }
142 };
143 }
144
145 // Create the abort callback
146 callback = callback( "abort" );
147
148 try {
149
150 // Do send the request (this may raise an exception)
151 xhr.send( options.hasContent && options.data || null );
152 } catch ( e ) {
153
154 // #14683: Only rethrow if this hasn't been notified as an error yet
155 if ( callback ) {
156 throw e;
157 }
158 }
159 },
160
161 abort: function() {
162 if ( callback ) {
163 callback();
164 }
165 }
166 };
167 }
168} );
169
170} );