HttpRequest#
Annotations: @Native.new("XMLHttpRequest")
A client-side XHR request for getting data from a URL, formally known as XMLHttpRequest.
Note: You should avoid directly using HttpRequest to make HTTP
requests. You can use HttpRequest indirectly through the
BrowserClient
adapter in package:http.
Using a higher-level library, like
package:http, allows you to switch
implementations with minimal changes to your code. For example,
package:http
Client
has implementations for the browser and implementations that use
platform native HTTP clients on Android and iOS.
HttpRequest can be used to obtain data from HTTP and FTP protocols, and is useful for AJAX-style page updates.
The simplest way to get the contents of a text file, such as a JSON-formatted file, is with getString. For example, the following code gets the contents of a JSON file and prints its length:
var path = 'myData.json';
HttpRequest.getString(path).then((String fileContents) {
print(fileContents.length);
}).catchError((error) {
print(error.toString());
});
Fetching data from other servers#
For security reasons, browsers impose restrictions on requests made by embedded apps. With the default behavior of this class, the code making the request must be served from the same origin (domain name, port, and application layer protocol) as the requested resource. In the example above, the myData.json file must be co-located with the app that uses it.
Other resources#
- Fetch data dynamically, a tutorial shows how to load data from a static file or from a server.
- Dart article on using HttpRequests
- JS XMLHttpRequest
- Using XMLHttpRequest
Inheritance
Object → EventTarget → HttpRequestEventTarget → HttpRequest
Constructors#
HttpRequest() factory#
General constructor for any type of request (GET, POST, etc).
This call is used in conjunction with open:
var request = new HttpRequest();
request.open('GET', 'http://dartlang.org');
request.onLoad.listen((event) => print(
'Request complete ${event.target.reponseText}'));
request.send();
is the (more verbose) equivalent of
HttpRequest.getString('http://dartlang.org').then(
(result) => print('Request complete: $result'));
Implementation
factory HttpRequest() {
return HttpRequest._create_1();
}
Properties#
hashCode no setter inherited#
Inherited from Interceptor.
Implementation
int get hashCode => Primitives.objectHashCode(this);
on no setter inherited#
This is an ease-of-use accessor for event streams which should only be used when an explicit accessor is not available.
Inherited from EventTarget.
Implementation
Events get on => new Events(this);
onAbort no setter inherited#
Stream of abort events handled by this HttpRequestEventTarget.
Inherited from HttpRequestEventTarget.
Implementation
Stream<ProgressEvent> get onAbort => abortEvent.forTarget(this);
onError no setter inherited#
Stream of error events handled by this HttpRequestEventTarget.
Inherited from HttpRequestEventTarget.
Implementation
Stream<ProgressEvent> get onError => errorEvent.forTarget(this);
onLoad no setter inherited#
Stream of load events handled by this HttpRequestEventTarget.
Inherited from HttpRequestEventTarget.
Implementation
Stream<ProgressEvent> get onLoad => loadEvent.forTarget(this);
onLoadEnd no setter inherited#
Stream of loadend events handled by this HttpRequestEventTarget.
Inherited from HttpRequestEventTarget.
Implementation
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
Stream<ProgressEvent> get onLoadEnd => loadEndEvent.forTarget(this);
onLoadStart no setter inherited#
Stream of loadstart events handled by this HttpRequestEventTarget.
Inherited from HttpRequestEventTarget.
Implementation
Stream<ProgressEvent> get onLoadStart => loadStartEvent.forTarget(this);
onProgress no setter inherited#
Stream of progress events handled by this HttpRequestEventTarget.
Inherited from HttpRequestEventTarget.
Implementation
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);
onReadyStateChange no setter#
Event listeners to be notified every time the HttpRequest
object's readyState changes values.
Implementation
Stream<Event> get onReadyStateChange => readyStateChangeEvent.forTarget(this);
onTimeout no setter inherited#
Stream of timeout events handled by this HttpRequestEventTarget.
Inherited from HttpRequestEventTarget.
Implementation
Stream<ProgressEvent> get onTimeout => timeoutEvent.forTarget(this);
readyState no setter#
Indicator of the current state of the request:
| Value | State | Meaning |
| 0 | unsent | open() has not yet been called |
| 1 | opened | send() has not yet been called |
| 2 | headers received | sent() has been called; response headers and status are available |
| 3 | loading | responseText holds some data |
| 4 | done | request is complete |
Implementation
int get readyState native;
response no setter#
The data received as a reponse from the request.
The data could be in the
form of a String,
ByteBuffer, Document,
Blob, or json (also a
String).
null indicates request failure.
Implementation
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
dynamic get response => _convertNativeToDart_XHR_Response(this._get_response);
responseHeaders no setter#
Returns all response headers as a key-value map.
Multiple values for the same header key can be combined into one, separated by a comma and a space.
See: http://www.w3.org/TR/XMLHttpRequest/#the-getresponseheader()-method
Implementation
Map<String, String> get responseHeaders {
// from Closure's goog.net.Xhrio.getResponseHeaders.
var headers = <String, String>{};
var headersString = this.getAllResponseHeaders();
if (headersString == null) {
return headers;
}
var headersList = headersString.split('\r\n');
for (var header in headersList) {
if (header.isEmpty) {
continue;
}
var splitIdx = header.indexOf(': ');
if (splitIdx == -1) {
continue;
}
var key = header.substring(0, splitIdx).toLowerCase();
var value = header.substring(splitIdx + 2);
if (headers.containsKey(key)) {
headers[key] = '${headers[key]}, $value';
} else {
headers[key] = value;
}
}
return headers;
}
responseText no setter#
The response in String form or empty String on failure.
Implementation
String? get responseText native;
responseType read / write#
String telling the server the desired response format.
Default is String.
Other options are one of 'arraybuffer', 'blob', 'document', 'json',
'text'. Some newer browsers will throw NS_ERROR_DOM_INVALID_ACCESS_ERR if
responseType is set while performing a synchronous request.
See also: MDN responseType
Implementation
String get responseType native;
set responseType(String value) native;
responseUrl no setter#
Implementation
@JSName('responseURL')
String? get responseUrl native;
responseXml no setter#
The request response, or null on failure.
The response is processed as
text/xml stream, unless responseType = 'document' and the request is
synchronous.
Implementation
@JSName('responseXML')
/**
* The request response, or null on failure.
*
* The response is processed as
* `text/xml` stream, unless responseType = 'document' and the request is
* synchronous.
*/
Document? get responseXml native;
runtimeType no setter inherited#
Inherited from Interceptor.
Implementation
Type get runtimeType =>
getRuntimeTypeOfInterceptorNotArray(getInterceptor(this), this);
status no setter#
The HTTP result code from the request (200, 404, etc). See also: HTTP Status Codes
Implementation
int? get status native;
statusText no setter#
The request response string (such as "OK"). See also: HTTP Status Codes
Implementation
String? get statusText native;
timeout read / write#
Length of time in milliseconds before a request is automatically terminated.
When the time has passed, an HttpRequestEventTarget.timeoutEvent is dispatched.
If timeout is set to 0, then the request will not time out.
Other resources
- XMLHttpRequest.timeout from MDN.
- The timeout attribute from W3C.
Implementation
int? get timeout native;
set timeout(int? value) native;
upload no setter#
EventTarget that can hold listeners to track the progress of the request.
Implementation
@Unstable()
HttpRequestUpload get upload native;
withCredentials read / write#
True if cross-site requests should use credentials such as cookies or authorization headers; false otherwise.
This value is ignored for same-site requests.
Implementation
bool? get withCredentials native;
set withCredentials(bool? value) native;
Methods#
abort()#
Stop the current request.
The request can only be stopped if readyState is HEADERS_RECEIVED or
LOADING. If this method is not in the process of being sent, the method
has no effect.
Implementation
void abort() native;
addEventListener() inherited#
Inherited from EventTarget.
Implementation
void addEventListener(
String type,
EventListener? listener, [
bool? useCapture,
]) {
// TODO(leafp): This check is avoid a bug in our dispatch code when
// listener is null. The browser treats this call as a no-op in this
// case, so it's fine to short-circuit it, but we should not have to.
if (listener != null) {
_addEventListener(type, listener, useCapture);
}
}
dispatchEvent() inherited#
Inherited from EventTarget.
Implementation
bool dispatchEvent(Event event) native;
getAllResponseHeaders()#
Retrieve all the response headers from a request.
null if no headers have been received. For multipart requests,
getAllResponseHeaders will return the response headers for the current
part of the request.
See also HTTP response headers for a list of common response headers.
Implementation
@Unstable()
String getAllResponseHeaders() native;
getResponseHeader()#
Return the response header named header, or null if not found.
See also HTTP response headers for a list of common response headers.
Implementation
@Unstable()
String? getResponseHeader(String name) native;
noSuchMethod() inherited#
Invoked when a nonexistent method or property is accessed.
A dynamic member invocation can attempt to call a member which doesn't exist on the receiving object. Example:
dynamic object = 1;
object.add(42); // Statically allowed, run-time error
This invalid code will invoke the noSuchMethod method
of the integer 1 with an Invocation
representing the
.add(42) call and arguments (which then throws).
Classes can override noSuchMethod to provide custom behavior for such invalid dynamic invocations.
A class with a non-default noSuchMethod invocation can also omit implementations for members of its interface. Example:
class MockList<T> implements List<T> {
noSuchMethod(Invocation invocation) {
log(invocation);
super.noSuchMethod(invocation); // Will throw.
}
}
void main() {
MockList().add(42);
}
This code has no compile-time warnings or errors even though
the MockList class has no concrete implementation of
any of the List interface methods.
Calls to List methods are forwarded to noSuchMethod,
so this code will log an invocation similar to
Invocation.method(#add, [42])
and then throw.
If a value is returned from noSuchMethod,
it becomes the result of the original invocation.
If the value is not of a type that can be returned by the original
invocation, a type error occurs at the invocation.
The default behavior is to throw a NoSuchMethodError.
Inherited from Interceptor.
Implementation
dynamic noSuchMethod(Invocation invocation) {
throw NoSuchMethodError.withInvocation(this, invocation);
}
open()#
Specify the desired url, and method to use in making the request.
By default the request is done asynchronously, with no user or password
authentication information. If async is false, the request will be sent
synchronously.
Calling open again on a currently active request is equivalent to
calling abort.
Note: Most simple HTTP requests can be accomplished using the getString,
request,
requestCrossOrigin, or
postFormData
methods. Use of this
open method is intended only for more complex HTTP requests where
finer-grained control is needed.
Implementation
void open(
String method,
String url, {
bool? async,
String? user,
String? password,
}) native;
overrideMimeType()#
Specify a particular MIME type (such as text/xml) desired for the
response.
This value must be set before the request has been sent. See also the list of IANA Official MIME types.
Implementation
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.SAFARI)
void overrideMimeType(String mime) native;
removeEventListener() inherited#
Inherited from EventTarget.
Implementation
void removeEventListener(
String type,
EventListener? listener, [
bool? useCapture,
]) {
// TODO(leafp): This check is avoid a bug in our dispatch code when
// listener is null. The browser treats this call as a no-op in this
// case, so it's fine to short-circuit it, but we should not have to.
if (listener != null) {
_removeEventListener(type, listener, useCapture);
}
}
send()#
Send the request with any given data.
Note: Most simple HTTP requests can be accomplished using the getString,
request,
requestCrossOrigin, or
postFormData
methods. Use of this
send method is intended only for more complex HTTP requests where
finer-grained control is needed.
Other resources
- XMLHttpRequest.send from MDN.
Implementation
void send([body_OR_data]) native;
setRequestHeader()#
Sets the value of an HTTP request header.
This method should be called after the request is opened, but before the request is sent.
Multiple calls with the same header will combine all their values into a single header.
Other resources
- XMLHttpRequest.setRequestHeader from MDN.
- The setRequestHeader() method from W3C.
Implementation
void setRequestHeader(String name, String value) native;
toString() inherited#
A string representation of this object.
Some classes have a default textual representation,
often paired with a static parse function (like int.parse).
These classes will provide the textual representation as
their string representation.
Other classes have no meaningful textual representation
that a program will care about.
Such classes will typically override toString to provide
useful information when inspecting the object,
mainly for debugging or logging.
Inherited from Interceptor.
Implementation
String toString() => Primitives.objectToHumanReadableString(this);
Operators#
operator ==() inherited#
The equality operator.
The default behavior for all Objects is to return true if and
only if this object and other are the same object.
Override this method to specify a different equality relation on a class. The overriding method must still be an equivalence relation. That is, it must be:
Total: It must return a boolean for all arguments. It should never throw.
Reflexive: For all objects
o,o == omust be true.-
Symmetric: For all objects
o1ando2,o1 == o2ando2 == o1must either both be true, or both be false. -
Transitive: For all objects
o1,o2, ando3, ifo1 == o2ando2 == o3are true, theno1 == o3must be true.
The method should also be consistent over time, so whether two objects are equal should only change if at least one of the objects was modified.
If a subclass overrides the equality operator, it should override the hashCode method as well to maintain consistency.
Inherited from Interceptor.
Implementation
bool operator ==(Object other) => identical(this, other);
Static Properties#
supportsCrossOrigin no setter#
Checks to see if the current platform supports making cross origin requests.
Note that even if cross origin requests are supported, they still may fail if the destination server does not support CORS requests.
Implementation
static bool get supportsCrossOrigin {
var xhr = new HttpRequest();
return JS('bool', '("withCredentials" in #)', xhr);
}
supportsLoadEndEvent no setter#
Checks to see if the LoadEnd event is supported on the current platform.
Implementation
static bool get supportsLoadEndEvent {
var xhr = new HttpRequest();
return JS('bool', '("onloadend" in #)', xhr);
}
supportsOverrideMimeType no setter#
Checks to see if the overrideMimeType method is supported on the current platform.
Implementation
static bool get supportsOverrideMimeType {
var xhr = new HttpRequest();
return JS('bool', '("overrideMimeType" in #)', xhr);
}
supportsProgressEvent no setter#
Checks to see if the Progress event is supported on the current platform.
Implementation
static bool get supportsProgressEvent {
var xhr = new HttpRequest();
return JS('bool', '("onprogress" in #)', xhr);
}
Static Methods#
getString()#
Creates a GET request for the specified url.
This is similar to request but specialized for HTTP GET requests which return text content.
To add query parameters, append them to the url following a ?,
joining each key to its value with = and separating key-value pairs with
&.
var name = Uri.encodeQueryComponent('John');
var id = Uri.encodeQueryComponent('42');
HttpRequest.getString('users.json?name=$name&id=$id')
.then((String resp) {
// Do something with the response.
});
See also:
Implementation
static Future<String> getString(
String url, {
bool? withCredentials,
void onProgress(ProgressEvent e)?,
}) {
return request(
url,
withCredentials: withCredentials,
onProgress: onProgress,
).then((HttpRequest xhr) => xhr.responseText!);
}
postFormData()#
Makes a server POST request with the specified data encoded as form data.
This is roughly the POST equivalent of getString. This method is similar to sending a FormData object with broader browser support but limited to String values.
If data is supplied, the key/value pairs are URI encoded with
Uri.encodeQueryComponent
and converted into an HTTP query string.
Unless otherwise specified, this method appends the following header:
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Here's an example of using this method:
var data = { 'firstName' : 'John', 'lastName' : 'Doe' };
HttpRequest.postFormData('/send', data).then((HttpRequest resp) {
// Do something with the response.
});
See also:
Implementation
static Future<HttpRequest> postFormData(
String url,
Map<String, String> data, {
bool? withCredentials,
String? responseType,
Map<String, String>? requestHeaders,
void onProgress(ProgressEvent e)?,
}) {
var parts = [];
data.forEach((key, value) {
parts.add(
'${Uri.encodeQueryComponent(key)}='
'${Uri.encodeQueryComponent(value)}',
);
});
var formData = parts.join('&');
if (requestHeaders == null) {
requestHeaders = <String, String>{};
}
requestHeaders.putIfAbsent(
'Content-Type',
() => 'application/x-www-form-urlencoded; charset=UTF-8',
);
return request(
url,
method: 'POST',
withCredentials: withCredentials,
responseType: responseType,
requestHeaders: requestHeaders,
sendData: formData,
onProgress: onProgress,
);
}
request()#
Creates and sends a URL request for the specified url.
By default request will perform an HTTP GET request, but a different
method (POST, PUT, DELETE, etc) can be used by specifying the
method parameter. (See also HttpRequest.postFormData
for POST
requests only.
The Future is completed when the response is available.
If specified, sendData will send data in the form of a ByteBuffer,
Blob,
Document, String, or
FormData along with the HttpRequest.
If specified, responseType sets the desired response format for the
request. By default it is String, but can also be 'arraybuffer', 'blob',
'document', 'json', or 'text'. See also HttpRequest.responseType
for more information.
The withCredentials parameter specified that credentials such as a cookie
(already) set in the header or
authorization headers
should be specified for the request. Details to keep in mind when using
credentials:
- Using credentials is only useful for cross-origin requests.
-
The
Access-Control-Allow-Originheader ofurlcannot contain a wildcard (*). - The
Access-Control-Allow-Credentialsheader ofurlmust be set to true. -
If
Access-Control-Expose-Headershas not been set to true, only a subset of all the response headers will be returned when calling getAllResponseHeaders.
The following is equivalent to the getString sample above:
var name = Uri.encodeQueryComponent('John');
var id = Uri.encodeQueryComponent('42');
HttpRequest.request('users.json?name=$name&id=$id')
.then((HttpRequest resp) {
// Do something with the response.
});
Here's an example of submitting an entire form with FormData.
var myForm = querySelector('form#myForm');
var data = new FormData(myForm);
HttpRequest.request('/submit', method: 'POST', sendData: data)
.then((HttpRequest resp) {
// Do something with the response.
});
Note that requests for file:// URIs are only supported by Chrome extensions with appropriate permissions in their manifest. Requests to file:// URIs will also never fail- the Future will always complete successfully, even when the file cannot be found.
See also: authorization headers.
Implementation
static Future<HttpRequest> request(
String url, {
String? method,
bool? withCredentials,
String? responseType,
String? mimeType,
Map<String, String>? requestHeaders,
sendData,
void onProgress(ProgressEvent e)?,
}) {
var completer = new Completer<HttpRequest>();
var xhr = new HttpRequest();
if (method == null) {
method = 'GET';
}
xhr.open(method, url, async: true);
if (withCredentials != null) {
xhr.withCredentials = withCredentials;
}
if (responseType != null) {
xhr.responseType = responseType;
}
if (mimeType != null) {
xhr.overrideMimeType(mimeType);
}
if (requestHeaders != null) {
requestHeaders.forEach((header, value) {
xhr.setRequestHeader(header, value);
});
}
if (onProgress != null) {
xhr.onProgress.listen(onProgress);
}
xhr.onLoad.listen((e) {
var status = xhr.status!;
var accepted = status >= 200 && status < 300;
var fileUri = status == 0; // file:// URIs have status of 0.
var notModified = status == 304;
// Redirect status is specified up to 307, but others have been used in
// practice. Notably Google Drive uses 308 Resume Incomplete for
// resumable uploads, and it's also been used as a redirect. The
// redirect case will be handled by the browser before it gets to us,
// so if we see it we should pass it through to the user.
var unknownRedirect = status > 307 && status < 400;
if (accepted || fileUri || notModified || unknownRedirect) {
completer.complete(xhr);
} else {
completer.completeError(e);
}
});
xhr.onError.listen(completer.completeError);
if (sendData != null) {
xhr.send(sendData);
} else {
xhr.send();
}
return completer.future;
}
requestCrossOrigin()#
Makes a cross-origin request to the specified URL.
This API provides a subset of request which works on IE9. If IE9 cross-origin support is not required then request should be used instead.
Implementation
static Future<String> requestCrossOrigin(
String url, {
String? method,
String? sendData,
}) {
if (supportsCrossOrigin) {
return request(url, method: method, sendData: sendData).then((xhr) {
return xhr.responseText!;
});
}
var completer = new Completer<String>();
if (method == null) {
method = 'GET';
}
var xhr = JS('var', 'new XDomainRequest()');
JS('', '#.open(#, #)', xhr, method, url);
JS(
'',
'#.onload = #',
xhr,
convertDartClosureToJS((e) {
var response = JS('String', '#.responseText', xhr);
completer.complete(response as FutureOr<String>?);
}, 1),
);
JS(
'',
'#.onerror = #',
xhr,
convertDartClosureToJS((e) {
completer.completeError(e);
}, 1),
);
// IE9 RTM - XDomainRequest issued requests may abort if all event handlers
// not specified
// http://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified
JS('', '#.onprogress = {}', xhr);
JS('', '#.ontimeout = {}', xhr);
JS('', '#.timeout = Number.MAX_VALUE', xhr);
if (sendData != null) {
JS('', '#.send(#)', xhr, sendData);
} else {
JS('', '#.send()', xhr);
}
return completer.future;
}
Constants#
DONE#
Implementation
static const int DONE = 4;
HEADERS_RECEIVED#
Implementation
static const int HEADERS_RECEIVED = 2;
LOADING#
Implementation
static const int LOADING = 3;
OPENED#
Implementation
static const int OPENED = 1;
readyStateChangeEvent#
Static factory designed to expose readystatechange events to event
handlers that are not necessarily instances of HttpRequest.
See EventStreamProvider for usage information.
Implementation
static const EventStreamProvider<Event> readyStateChangeEvent =
const EventStreamProvider<Event>('readystatechange');
UNSENT#
Implementation
static const int UNSENT = 0;