代码之家  ›  专栏  ›  技术社区  ›  simont basooli

在jquery.ajax请求中使用reviver函数

  •  2
  • simont basooli  · 技术社区  · 7 年前

    我有Ajax响应 key,value 成对引用。我想从任何数值中删除引号。对于所有的Ajax请求,我需要在全局范围内完成这项工作,只需最少的工作量。

    我正在使用 jQuery.getJSON 对于大多数请求,我想要一个不需要单独调整每个当前Ajax请求的解决方案。(我不想添加 JSON.parse(text,myreviver) 调用现有的每一个 $.getJSON 电话)

    例如:

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

    我该怎么做? 对于所有Ajax请求 ?

    我目前的最终目标是 JSON.parse(text, reviver) 处理数据(感谢 this question )我不知道怎么把这个钩住 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.
    }
    

    我怎样才能:

    • 杰克森
    • 在全局中处理Ajax响应 success 功能 之前 它达到了其他的成功功能?
    2 回复  |  直到 7 年前
        1
  •  0
  •   Yury Tarabanko    7 年前

    您可以使用 ajaxSetup “对于所有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>
        2
  •  1
  •   CertainPerformance    7 年前

    您可以覆盖 .getJSON 用你自己的方法。

    土著人 getJSON 方法如下:

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

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

    这是一件很简单的事情,可以接受传递给 盖特森 通过你的 拥有 回调到 jQuery.get 具有 'text' 而不是 'json' ,使用自定义的reviver解析JSON,然后调用原始回调。

    一个复杂的问题是,第二个参数传递给 盖特森 是可选的(与请求一起发送的数据)。

    假设始终使用success函数(第三个和最后一个参数),则可以使用rest参数和 pop() 以获得传递的成功函数。创建一个自定义成功函数,该函数接受文本响应并使用自定义 JSON.parse ,然后用创建的对象调用传递的success函数。

    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 如果没有成功的回调,则需要覆盖 then 返回的promise的属性,尽管处理可选的success回调会使代码的逻辑更加糟糕:

    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>