【问题标题】:Why does a FormData object work but not a regular object in Jquery AJAX submit?为什么在 Jquery AJAX 提交中 FormData 对象有效但不是常规对象?
【发布时间】:2021-04-30 01:37:04
【问题描述】:

我对在我的 AJAX 提交中使用 data 对象感到困惑。

这是我提交的 AJAX 脚本:

$.ajax({
  url:'/library/php/triggers.php',
  type:'POST',
  data:data,
  cache:false,
  dataType:'json',
  processData:false,
  contentType:false,
  success:function(result){console.log(result);}
});

这个data 有效:

 var data=new FormData(this);
 data.append('hello','my friend');

但是这个data 不起作用:

var data={"hello":"my friend"};

这两个不是 JSON 对象吗?这些有什么区别?

我也尝试将contentType:false 更改为contentType:'application/json',但没有成功。

【问题讨论】:

    标签: jquery ajax post


    【解决方案1】:

    要解决两者之间的差异: 如果你这样做了

    var data = new FormData();
    data.append('hello', 'my friend');
    
    console.log(data)
    var data2 = {
      "hello": "my friend"
    };
    

    然后检查您的开发工具,您会发现:

        FormData {  }  ​
        <prototype>: FormDataPrototype { append: append(), delete: delete(), get: get(), … }
        append: function append()
        constructor: function ()
        delete: function delete()
        entries: function entries()
        forEach: function forEach()
        get: function get()
        getAll: function getAll()
        has: function has()
        keys: function keys()
        set: function set()
        values: function values()
        Symbol(Symbol.toStringTag): "FormData"
        Symbol(Symbol.iterator): 
    function entries()`<prototype>: Object { … }
    

    Form.data() 在构造函数associated with methods 中有很多其他属性可供您使用,因此浏览器会以不同的方式处理它。
    最后一个函数:function entries() &lt;prototype&gt;: Object { … } 与使用 getter 和 setter 存储数据的常规对象相同:

    Object { hello: "my friend" }
    ​
    hello: "my friend"
    ​
    <prototype>: Object { … }
    __defineGetter__: function __defineGetter__()
    __defineSetter__: function __defineSetter__()
    __lookupGetter__: function __lookupGetter__()
    __lookupSetter__: function __lookupSetter__()
    __proto__: 
    constructor: function Object()
    hasOwnProperty: function hasOwnProperty()
    isPrototypeOf: function isPrototypeOf()
    propertyIsEnumerable: function propertyIsEnumerable()
    toLocaleString: function toLocaleString()
    toString: function toString()
    valueOf: function valueOf()
    <get __proto__()>: function __proto__()
    <set __proto__()>: function __proto__()
    

    还请注意,您上次创建的对象将您的字符串 'hello' 转换为键 hello: 而表单数据将所有键和值转换为字符串。

    所以,总之这两个不是同一个对象。

    【讨论】:

      【解决方案2】:

      processing:false 是因为浏览器内部处理 FormData 对象的方式与提交&lt;form&gt; 时相同。

      您希望 jQuery 处理普通对象。它在内部使用$.param() 来创建表单编码字符串

      var data = {"hello":"my friend"};
      
      $.ajax({
        url:'/library/php/triggers.php',
        type:'POST',
        data:data,  
        dataType:'json',// what you expect to recieve  
        success:function(result){console.log(result);}
      });
      

      在 php 中接收:

      $hello = $_POST['hello'];
      

      jQuery 在内部对对象做了什么:

      var data = {"hello":"my friend", foo:"bar"};
      
      var processed = $.param(data);
      
      console.log(processed)
      &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"&gt;&lt;/script&gt;

      【讨论】:

      • $.param 在我有 contentType:false 时对我不起作用,但如果我删除 contentType:false,FormData 将不起作用。
      • 您不需要自己使用 $.param,甚至不需要知道它的存在。我只是为了解释内部做了什么而展示了它。至于 FormData,浏览器设置内容类型标题
      猜你喜欢
      • 1970-01-01
      • 2015-09-04
      • 2015-12-01
      • 2015-03-11
      • 1970-01-01
      • 2011-09-20
      • 1970-01-01
      • 2012-02-29
      相关资源
      最近更新 更多