api-request.js 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /**
  2. * Thin jQuery.ajax wrapper for WP REST API requests.
  3. *
  4. * Currently only applies to requests that do not use the `wp-api.js` Backbone
  5. * client library, though this may change. Serves several purposes:
  6. *
  7. * - Allows overriding these requests as needed by customized WP installations.
  8. * - Sends the REST API nonce as a request header.
  9. * - Allows specifying only an endpoint namespace/path instead of a full URL.
  10. *
  11. * @since 4.9.0
  12. * @output wp-includes/js/api-request.js
  13. */
  14. ( function( $ ) {
  15. var wpApiSettings = window.wpApiSettings;
  16. function apiRequest( options ) {
  17. options = apiRequest.buildAjaxOptions( options );
  18. return apiRequest.transport( options );
  19. }
  20. apiRequest.buildAjaxOptions = function( options ) {
  21. var url = options.url;
  22. var path = options.path;
  23. var namespaceTrimmed, endpointTrimmed, apiRoot;
  24. var headers, addNonceHeader, headerName;
  25. if (
  26. typeof options.namespace === 'string' &&
  27. typeof options.endpoint === 'string'
  28. ) {
  29. namespaceTrimmed = options.namespace.replace( /^\/|\/$/g, '' );
  30. endpointTrimmed = options.endpoint.replace( /^\//, '' );
  31. if ( endpointTrimmed ) {
  32. path = namespaceTrimmed + '/' + endpointTrimmed;
  33. } else {
  34. path = namespaceTrimmed;
  35. }
  36. }
  37. if ( typeof path === 'string' ) {
  38. apiRoot = wpApiSettings.root;
  39. path = path.replace( /^\//, '' );
  40. // API root may already include query parameter prefix if site is
  41. // configured to use plain permalinks.
  42. if ( 'string' === typeof apiRoot && -1 !== apiRoot.indexOf( '?' ) ) {
  43. path = path.replace( '?', '&' );
  44. }
  45. url = apiRoot + path;
  46. }
  47. // If ?_wpnonce=... is present, no need to add a nonce header.
  48. addNonceHeader = ! ( options.data && options.data._wpnonce );
  49. headers = options.headers || {};
  50. // If an 'X-WP-Nonce' header (or any case-insensitive variation
  51. // thereof) was specified, no need to add a nonce header.
  52. if ( addNonceHeader ) {
  53. for ( headerName in headers ) {
  54. if ( headers.hasOwnProperty( headerName ) ) {
  55. if ( headerName.toLowerCase() === 'x-wp-nonce' ) {
  56. addNonceHeader = false;
  57. break;
  58. }
  59. }
  60. }
  61. }
  62. if ( addNonceHeader ) {
  63. // Do not mutate the original headers object, if any.
  64. headers = $.extend( {
  65. 'X-WP-Nonce': wpApiSettings.nonce
  66. }, headers );
  67. }
  68. // Do not mutate the original options object.
  69. options = $.extend( {}, options, {
  70. headers: headers,
  71. url: url
  72. } );
  73. delete options.path;
  74. delete options.namespace;
  75. delete options.endpoint;
  76. return options;
  77. };
  78. apiRequest.transport = $.ajax;
  79. /** @namespace wp */
  80. window.wp = window.wp || {};
  81. window.wp.apiRequest = apiRequest;
  82. } )( jQuery );