簡體   English   中英

在 jQuery.ajax 請求中使用 reviver 函數

[英]Use reviver function in jQuery.ajax requests

我有 AJAX 響應,其中引用了所有key,value對。 我想從任何數字值中刪除引號。 我需要在全局范圍內為所有 AJAX 請求執行此操作,並且只需最少的努力。

我對大多數請求使用jQuery.getJSON ,我想要一個不需要單獨調整每個當前 AJAX 請求的解決方案。 (我不想在每個現有的$.getJSON調用中添加一個JSON.parse(text,myreviver)調用。)

例如:

Received:    {"age":"31", "money": "-1.329"}
Want:        {"age": 31, "money": -1.329}

對於所有 AJAX 請求,我該怎么做?

我目前的最終目標是使用JSON.parse(text, reviver)來處理數據(感謝這個問題)。 不過,我不知道如何將其掛接到jQuery.ajax

我曾嘗試使用ajaxSuccess() ,但它似乎沒有對任何數據進行鏈式處理。 例如:

$(document.ajaxSuccess) ( function(j) {
    JSON.parse(j, myReviver);
}

.getJSON(url, data, function(j) {
    // The data in this success function has not been through myReviver.
}

我怎樣才能:

  • jQuery.getJSON使用 reviver 函數,或
  • 到達其他成功函數之前處理全局success函數中的 AJAX 響應?

您可以使用ajaxSetup將默認文本覆蓋為 json 轉換器“全局,對於所有 AJAX 請求,只需最少的努力。”

 $.ajaxSetup({ converters: { // default was jQuery.parseJSON 'text json': data => JSON.parse(data, numberReviver) } }) $.getJSON('https://jsonplaceholder.typicode.com/users') .then(users => users.map(user => ({email: user.email, geo: user.address.geo}))) .then(console.log) function numberReviver(name, value) { if(typeof value === 'string' && /^[+-]?[0-9]+(?:\\.[0-9]+)$/.test(value)) { console.log(`Using custom reviver for ${name}:${value}`) value = Number(value) } return value }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

您可以使用自己的方法覆蓋.getJSON

本機getJSON方法可以在這里看到:

https://j11y.io/jquery/#v=git&fn=jQuery.getJSON

function (url, data, callback) {
  return jQuery.get(url, data, callback, "json");
}

獲取傳遞給getJSON的回調非常簡單,使用'text'而不是'json'將您自己的回調傳遞給jQuery.get ,使用自定義 reviver 解析 JSON,然后調用原始回調。

一個復雜的問題是傳遞給getJSON的第二個參數是可選的(與請求一起發送的數據)。

假設您總是使用成功函數(第三個和最后一個參數),您可以使用 rest 參數和pop()來獲取傳遞的成功函數。 創建一個自定義成功函數,該函數接受文本響應並使用自定義JSON.parse ,然后使用創建的對象調用傳遞的成功函數。

 const dequoteDigits = json => JSON.parse( json, (key, val) => ( typeof val === 'string' && /^[+-]?[0-9]+(?:\\.[0-9]+)$/.test(val) ? Number(val) : val ) ); jQuery.getJSON = function (url, ...rest) { // normal parameters: url, data (optional), success const success = rest.pop(); const customSuccess = function(textResponse, status, jqXHR) { const obj = dequoteDigits(textResponse); success.call(this, obj, status, jqXHR); }; // spread the possibly-empty empty array "rest" to put "data" into argument list return jQuery.get(url, ...rest, customSuccess, 'text'); }; jQuery.getJSON('https://jsonplaceholder.typicode.com/users', (obj) => { console.log(obj); });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

上面的代碼片段輸出與請求的 URL 之間的差異

https://jsonplaceholder.typicode.com/users

是緯度和經度屬性值已轉換為數字,而不是剩余的字符串。

如果你在沒有成功回調的情況下也使用過await ,那么你需要覆蓋返回的 Promise 的then屬性,盡管處理可選的成功回調會使代碼的邏輯變得更加丑陋:

 const dequoteDigits = json => JSON.parse( json, (key, val) => ( typeof val === 'string' && /^[+-]?[0-9]+(?:\\.[0-9]+)$/.test(val) ? Number(val) : val ) ); jQuery.getJSON = function (url, ...rest) { // normal parameters: url, data (optional), success (optional) const data = rest.length && typeof rest[0] !== 'function' ? [rest.shift()] : []; const newSuccessArr = typeof rest[0] === 'function' ? [function(textResponse, status, jqXHR) { const obj = dequoteDigits(textResponse); rest[0].call(this, obj, status, jqXHR); } ] : []; // spread the possibly-empty dataObj and newSuccessObj into the new argument list array const newArgs = [url, ...data, ...newSuccessArr, 'text']; const prom = jQuery.get.apply(this, newArgs); const nativeThen = prom.then; prom.then = function(resolve) { nativeThen.call(this) .then((res) => { const obj = dequoteDigits(this.responseText); resolve(obj); }); }; return prom; }; jQuery.getJSON('https://jsonplaceholder.typicode.com/users', (obj) => { console.log(obj[0].address.geo); }); (async () => { const obj = await jQuery.getJSON('https://jsonplaceholder.typicode.com/users'); console.log(obj[0].address.geo); // console.log(obj); })();
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM