2
Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
3
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
4
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
5
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
6
Code distributed by Google as part of the polymer project is also
7
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
10
<link rel="import" href="../polymer/polymer.html">
11
<link rel="import" href="iron-request.html">
14
The `iron-ajax` element exposes network request functionality.
18
url="http://gdata.youtube.com/feeds/api/videos/"
19
params='{"alt":"json", "q":"chrome"}'
21
on-response="handleResponse"
22
debounce-duration="300"></iron-ajax>
24
With `auto` set to `true`, the element performs a request whenever
25
its `url`, `params` or `body` properties are changed. Automatically generated
26
requests will be debounced in the case that multiple attributes are changed
29
Note: The `params` attribute must be double quoted JSON.
31
You can trigger a request explicitly by calling `generateRequest` on the
46
* Fired when a request is sent.
52
* Fired when a response is received.
58
* Fired when an error is received.
69
* The URL target of the request.
76
* An object that contains query parameters to be appended to the
77
* specified `url` when generating a request. If you wish to set the body
78
* content when making a POST request, you should use the `body` property
89
* The HTTP method to use such as 'GET', 'POST', 'PUT', or 'DELETE'.
98
* HTTP request headers to send.
104
* url="http://somesite.com"
105
* headers='{"X-Requested-With": "XMLHttpRequest"}'
106
* handle-as="json"></iron-ajax>
108
* Note: setting a `Content-Type` header here will override the value
109
* specified by the `contentType` property of this element.
119
* Content type to use when sending data. If the `contentType` property
120
* is set and a `Content-Type` header is specified in the `headers`
121
* property, the `headers` property value will take precedence.
123
* Varies the handling of the `body` param.
131
* Body content to send with the request, typically used with "POST"
134
* If body is a string it will be sent unmodified.
136
* If Content-Type is set to a value listed below, then
137
* the body will be encoded accordingly.
139
* * `content-type="application/json"`
140
* * body is encoded like `{"foo":"bar baz","x":1}`
141
* * `content-type="application/x-www-form-urlencoded"`
142
* * body is encoded like `foo=bar+baz&x=1`
144
* Otherwise the body will be passed to the browser unmodified, and it
145
* will handle any encoding (e.g. for FormData, Blob, ArrayBuffer).
147
* @type (ArrayBuffer|ArrayBufferView|Blob|Document|FormData|null|string|undefined|Object)
155
* Toggle whether XHR is synchronous or asynchronous. Don't change this
156
* to true unless You Know What You Are Doing™.
164
* Specifies what data to store in the `response` property, and
165
* to deliver as `event.detail.response` in `response` events.
169
* `text`: uses `XHR.responseText`.
171
* `xml`: uses `XHR.responseXML`.
173
* `json`: uses `XHR.responseText` parsed as JSON.
175
* `arraybuffer`: uses `XHR.response`.
177
* `blob`: uses `XHR.response`.
179
* `document`: uses `XHR.response`.
187
* Set the withCredentials flag on the request.
195
* Set the timeout flag on the request.
203
* If true, automatically performs an Ajax request when either `url` or
212
* If true, error messages will automatically be logged to the console.
220
* The most recent request made by this iron-ajax element.
229
* True while lastRequest is in flight.
238
* lastRequest's response.
240
* Note that lastResponse and lastError are set when lastRequest finishes,
241
* so if loading is true, then lastResponse and lastError will correspond
242
* to the result of the previous request.
244
* The type of the response is determined by the value of `handleAs` at
245
* the time that the request was generated.
256
* lastRequest's error, if any.
267
* An Array of all in-flight requests originating from this iron-ajax
280
* Length of time in milliseconds to debounce multiple automatically generated requests.
289
* Prefix to be stripped from a JSON response before parsing it.
291
* In order to prevent an attack using CSRF with Array responses
292
* (http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx/)
293
* many backends will mitigate this by prefixing all JSON response bodies
294
* with a string that would be nonsensical to a JavaScript parser.
303
* By default, these events do not bubble largely because the `error` event has special
304
* meaning in the window object. Setting this attribute will cause iron-ajax's request,
305
* response, and error events to bubble to the window object.
312
_boundHandleResponse: {
315
return this._handleResponse.bind(this);
321
'_requestOptionsChanged(url, method, params.*, headers, contentType, ' +
322
'body, sync, handleAs, jsonPrefix, withCredentials, timeout, auto)'
326
* The query string that should be appended to the `url`, serialized from
327
* the current value of `params`.
336
for (param in this.params) {
337
value = this.params[param];
338
param = window.encodeURIComponent(param);
340
if (Array.isArray(value)) {
341
for (var i = 0; i < value.length; i++) {
342
queryParts.push(param + '=' + window.encodeURIComponent(value[i]));
344
} else if (value !== null) {
345
queryParts.push(param + '=' + window.encodeURIComponent(value));
347
queryParts.push(param);
351
return queryParts.join('&');
355
* The `url` with query string (if `params` are specified), suitable for
356
* providing to an `iron-request` instance.
361
var queryString = this.queryString;
364
var bindingChar = this.url.indexOf('?') >= 0 ? '&' : '?';
365
return this.url + bindingChar + queryString;
372
* An object that maps header names to header values, first applying the
373
* the value of `Content-Type` and then overlaying the headers specified
374
* in the `headers` property.
378
get requestHeaders() {
380
var contentType = this.contentType;
381
if (contentType == null && (typeof this.body === 'string')) {
382
contentType = 'application/x-www-form-urlencoded';
385
headers['content-type'] = contentType;
389
if (this.headers instanceof Object) {
390
for (header in this.headers) {
391
headers[header] = this.headers[header].toString();
399
* Request options suitable for generating an `iron-request` instance based
400
* on the current state of the `iron-ajax` instance's properties.
404
* method: (string|undefined),
405
* async: (boolean|undefined),
406
* body: (ArrayBuffer|ArrayBufferView|Blob|Document|FormData|null|string|undefined|Object),
407
* headers: (Object|undefined),
408
* handleAs: (string|undefined),
409
* jsonPrefix: (string|undefined),
410
* withCredentials: (boolean|undefined)}}
412
toRequestOptions: function() {
414
url: this.requestUrl || '',
416
headers: this.requestHeaders,
419
handleAs: this.handleAs,
420
jsonPrefix: this.jsonPrefix,
421
withCredentials: this.withCredentials,
422
timeout: this.timeout
427
* Performs an AJAX request to the specified URL.
429
* @return {!IronRequestElement}
431
generateRequest: function() {
432
var request = /** @type {!IronRequestElement} */ (document.createElement('iron-request'));
433
var requestOptions = this.toRequestOptions();
435
this.activeRequests.push(request);
437
request.completes.then(
438
this._boundHandleResponse
440
this._handleError.bind(this, request)
442
this._discardRequest.bind(this, request)
445
request.send(requestOptions);
447
this._setLastRequest(request);
448
this._setLoading(true);
450
this.fire('request', {
452
options: requestOptions
453
}, {bubbles: this.bubbles});
458
_handleResponse: function(request) {
459
if (request === this.lastRequest) {
460
this._setLastResponse(request.response);
461
this._setLastError(null);
462
this._setLoading(false);
464
this.fire('response', request, {bubbles: this.bubbles});
467
_handleError: function(request, error) {
469
console.error(error);
472
if (request === this.lastRequest) {
477
this._setLastResponse(null);
478
this._setLoading(false);
483
}, {bubbles: this.bubbles});
486
_discardRequest: function(request) {
487
var requestIndex = this.activeRequests.indexOf(request);
489
if (requestIndex > -1) {
490
this.activeRequests.splice(requestIndex, 1);
494
_requestOptionsChanged: function() {
495
this.debounce('generate-request', function() {
496
if (this.url == null) {
501
this.generateRequest();
503
}, this.debounceDuration);