简体   繁体   中英

Jquery ajax request done and fail with Axios

I have a custom API setup as:

export default class API {

  static send(verb, resource, raw_params, callback, errcallback) {

    let org_id = window.localStorage._organization_id,
      params = Object.keys(raw_params).reduce(function(o, k) {
      o[k] = raw_params[k];
      return o;
    }, {});

    errcallback = typeof errcallback === 'function' ? errcallback : function() {};

    if (!!org_id && !params.hasOwnProperty('organization_id')) {
      params.organization_id = org_id;
    }

    $.ajax({
      url: URL + '/' + resource,
      type: verb,
      data: params
      xhrFields: { withCredentials: true }
    })
    .done(callback)
    .fail(errcallback);
  }

  static get(resource, params, callback, errcallback) {
    API.send('GET', resource, params, callback, errcallback);
  }

  static post(resource, params, callback, errcallback) {
    API.send('POST', resource, params, callback, errcallback);
  }

  static put(resource, params, callback, errcallback) {
    API.send('PUT', resource, params, callback, errcallback);
  }

  static del(resource, params, callback, errcallback) {
    API.send('DELETE', resource, params, callback, errcallback);
  }
}

Then I can make an API request from any file in my application as:

API.post('x/y', {params}, res => {
  this.setState(res);
}, (xhr) => {
  const errorMessage = JSON.parse(xhr.responseText).message;
  alert('error', 5000, errorMessage);
}

I am trying to replace this with axios and I replaced the $.ajax request with the following:

axios({
  method: verb,
  url: `${URL}/${resource}`,
  data: params,
  xhrFields: { withCredentials: true }
})
 .then(callback)
 .catch(errcallback)

But it doesn't call the response or error callback. Is there a way I can update this class to handle that or do I have to replace every request with an axios request instead and use the axios defined res and xhr ?

Axios by default posts data as application/json whereas jQuery defaults to application/x-www-form-urlencoded . See https://github.com/axios/axios#using-applicationx-www-form-urlencoded-format .

Also, while jQuery uses data as the query parameters for GET requests, Axios separates request body payloads and query parameters into the data and params properties, respectively.

With that in mind, to drop-in-replace jQuery with Axios, you would need to do the following...

const request = {
  method: verb,
  url: `${URL}/${resource}`,
  withCredentials: true      // 👈 are you sure you need this?
}
if (verb === 'GET' || verb === 'DELETE') {
  request.params = params // query params, no request body
} else {
  /// set appropriate request content-type
  request.headers = { 'content-type': 'application/x-www-form-urlencoded' }

  // convert "params" object into request body string
  request.data = Object.entries(params).reduce((data, [key, value]) => {
    data.append(key, value)
    return data
  }, new URLSearchParams())
}
axios(request).then(callback).catch(errcallback)

The Object.entries(params).reduce(...) thing is just a simplified example of producing an application/x-www-form-urlencoded string from a flat object. Axios itself recommends the qs library .

Also keep in mind that Object.entries() is not available in any version of Internet Explorer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM