1 |
|
2 |
|
3 | /**
|
4 | * Base object Ajax
|
5 | */
|
6 | export var Ajax = {
|
7 |
|
8 | /**
|
9 | * Sends an async HTTP (AJAX) request or if last parameter is false - returns created instance
|
10 | * with ability to modify native XMLHttpRequest (.request property) and manually send request when needed.
|
11 | *
|
12 | * @param {string} method - HTTP method (GET, POST, HEAD, ...)
|
13 | * @param {string} url - URI for current domain or full URL for cross domain AJAX request
|
14 | * Please note that in cross domain requests only GET, POST and HEAD methods allowed as well as
|
15 | * only few headers available. For more info visit
|
16 | * https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
|
17 | * @param {object} data - key: value pair of data to send. Data is automatically URL encoded
|
18 | * @param {callback(responseText)} on_success - callback on response with status code 200
|
19 | * @param {callback(responseText, responseStatusCode)} on_error = null - custom handler
|
20 | * for response with status code different from 200
|
21 | * @param {object} headers = {} - key: value map of headers to send
|
22 | * @param {boolean} do_send = true - instantly makes requests
|
23 | *
|
24 | * @returns {Object}
|
25 | */
|
26 | create(method, url, data, on_success, on_error = null, headers = {}, do_send = true) {
|
27 |
|
28 | var t = Object.create(this);
|
29 | t.method = method;
|
30 | t.url = url;
|
31 | t.data = data;
|
32 | t.request = new XMLHttpRequest();
|
33 | t.onSuccess = on_success;
|
34 | t.onError = on_error;
|
35 | t.headers = headers;
|
36 | t.request.onreadystatechange = function() {
|
37 | if (t.request.readyState === XMLHttpRequest.DONE) {
|
38 | if (t.request.status === 200) {
|
39 | t.onSuccess(t.request.responseText);
|
40 | } else {
|
41 | if (t.onError !== null) {
|
42 | t.onError(t.request.responseText, t.request.status);
|
43 | } else {
|
44 | console.error('Bunny AJAX error: unhandled error with response status ' + t.request.status + ' and body: ' + t.request.responseText);
|
45 | }
|
46 | }
|
47 | }
|
48 | };
|
49 |
|
50 | if (do_send) {
|
51 | t.send();
|
52 | }
|
53 |
|
54 | return t;
|
55 | },
|
56 |
|
57 | /**
|
58 | * Should be called on instance created with factory Ajax.create() method
|
59 | * Opens request, applies headers, builds data URL encoded string and sends request
|
60 | */
|
61 | send() {
|
62 |
|
63 | this.request.open(this.method, this.url);
|
64 |
|
65 | for (var header in this.headers) {
|
66 | this.request.setRequestHeader(header, this.headers[header]);
|
67 | }
|
68 |
|
69 | var str_data = '';
|
70 |
|
71 | if (this.data instanceof FormData) {
|
72 | this.request.send(this.data);
|
73 | } else {
|
74 | for(var name in this.data) {
|
75 | str_data = str_data + name + '=' + encodeURIComponent(this.data[name]) + '&';
|
76 | }
|
77 | this.request.send(str_data);
|
78 | }
|
79 |
|
80 | },
|
81 |
|
82 | /**
|
83 | * Sends a form via ajax POST with header Content-Type: application/x-www-form-urlencoded
|
84 | * Data is automatically taken form all form input values
|
85 | *
|
86 | * @param {object} form_el - Form document element
|
87 | * @param {callback(responseText)} on_success - callback for status code 200
|
88 | * @param {callback(responseText, responseStatusCode)} on_error = null - custom handler for non 200 status codes
|
89 | * @param {object} headers = {'Content-Type': 'application/x-www-form-urlencoded'} - key: value map of headers
|
90 | */
|
91 | sendForm(form_el, on_success, on_error = null, headers = {'Content-Type': 'application/x-www-form-urlencoded'}) {
|
92 | var data = {};
|
93 | form_el.querySelectorAll('[name]').forEach(function(input){
|
94 | data[input.getAttribute('name')] = input.value;
|
95 | });
|
96 | this.create('POST', form_el.getAttribute('action'), data, on_success, on_error, headers, true);
|
97 | },
|
98 |
|
99 | /**
|
100 | * Sends a form via ajax POST with header Content-Type: multipart/form-data which is required for file uploading
|
101 | * Data is automatically taken form all form input values
|
102 | *
|
103 | * @param {object} form_el - Form document element
|
104 | * @param {callback(responseText)} on_success - callback for status code 200
|
105 | * @param {callback(responseText, responseStatusCode)} on_error = null - custom handler for non 200 status codes
|
106 | * @param {object} headers = {'Content-Type': 'multipart/form-data'} - key: value map of headers
|
107 | */
|
108 | sendFormWithFiles(form_el, on_success, on_error = null, headers = {'Content-Type': 'multipart/form-data'}) {
|
109 | this.sendForm(form_el, on_success, on_error, headers);
|
110 | },
|
111 |
|
112 | /**
|
113 | * Sends a simple GET request. By default adds header X-Requested-With: XMLHttpRequest
|
114 | * which allows back-end applications to detect if request is ajax.
|
115 | * However for making a cross domain requests this header might not be acceptable
|
116 | * and in this case pass an empty object {} as a last argument to send no headers
|
117 | *
|
118 | * @param {string} url - URI or full URL for cross domain requests
|
119 | * @param {callback(responseText)} on_success - callback for status code 200
|
120 | * @param {callback(responseText, responseStatusCode)} on_error = null - custom handler for non 200 status codes
|
121 | * @param headers = {'X-Requested-With': 'XMLHttpRequest'} key: value map of headers
|
122 | */
|
123 | get: function(url, on_success, on_error = null, headers = {'X-Requested-With': 'XMLHttpRequest'}) {
|
124 | this.create('GET', url, {}, on_success, on_error, headers, true);
|
125 | },
|
126 |
|
127 | post: function(url, data, on_success, on_error = null, headers = {'X-Requested-With': 'XMLHttpRequest'}) {
|
128 | this.create('POST', url, data, on_success, on_error, headers, true);
|
129 | }
|
130 |
|
131 | };
|