3 * Perform a HTTP GET request.
4 * Can easily pass query parameters as the second parameter.
6 * @param {Object} params
7 * @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
9 async function get(url, params = {}) {
17 * Perform a HTTP POST request.
19 * @param {Object} data
20 * @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
22 async function post(url, data = null) {
23 return dataRequest('POST', url, data);
27 * Perform a HTTP PUT request.
29 * @param {Object} data
30 * @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
32 async function put(url, data = null) {
33 return dataRequest('PUT', url, data);
37 * Perform a HTTP PATCH request.
39 * @param {Object} data
40 * @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
42 async function patch(url, data = null) {
43 return dataRequest('PATCH', url, data);
47 * Perform a HTTP DELETE request.
49 * @param {Object} data
50 * @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
52 async function performDelete(url, data = null) {
53 return dataRequest('DELETE', url, data);
57 * Perform a HTTP request to the back-end that includes data in the body.
58 * Parses the body to JSON if an object, setting the correct headers.
59 * @param {String} method
61 * @param {Object} data
62 * @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
64 async function dataRequest(method, url, data = null) {
70 // Send data as JSON if a plain object
71 if (typeof data === 'object' && !(data instanceof FormData)) {
73 'Content-Type': 'application/json',
74 'X-Requested-With': 'XMLHttpRequest',
76 options.body = JSON.stringify(data);
79 // Ensure FormData instances are sent over POST
80 // Since Laravel does not read multipart/form-data from other types
81 // of request. Hence the addition of the magic _method value.
82 if (data instanceof FormData && method !== 'post') {
83 data.append('_method', method);
84 options.method = 'post';
87 return request(url, options)
91 * Create a new HTTP request, setting the required CSRF information
92 * to communicate with the back-end. Parses & formats the response.
94 * @param {Object} options
95 * @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
97 async function request(url, options = {}) {
98 if (!url.startsWith('http')) {
99 url = window.baseUrl(url);
102 if (options.params) {
103 const urlObj = new URL(url);
104 for (let paramName of Object.keys(options.params)) {
105 const value = options.params[paramName];
106 if (typeof value !== 'undefined' && value !== null) {
107 urlObj.searchParams.set(paramName, value);
110 url = urlObj.toString();
113 const csrfToken = document.querySelector('meta[name=token]').getAttribute('content');
114 options = Object.assign({}, options, {
115 'credentials': 'same-origin',
117 options.headers = Object.assign({}, options.headers || {}, {
118 'baseURL': window.baseUrl(''),
119 'X-CSRF-TOKEN': csrfToken,
122 const response = await fetch(url, options);
123 const content = await getResponseContent(response);
126 headers: response.headers,
127 redirected: response.redirected,
128 status: response.status,
129 statusText: response.statusText,
142 * Get the content from a fetch response.
143 * Checks the content-type header to determine the format.
144 * @param {Response} response
145 * @returns {Promise<Object|String>}
147 async function getResponseContent(response) {
148 if (response.status === 204) {
152 const responseContentType = response.headers.get('Content-Type') || '';
153 const subType = responseContentType.split(';')[0].split('/').pop();
155 if (subType === 'javascript' || subType === 'json') {
156 return await response.json();
159 return await response.text();
167 delete: performDelete,