【问题标题】:new FormData() "application/x-www-form-urlencoded"新 FormData() "应用程序/x-www-form-urlencoded"
【发布时间】:2011-09-24 23:21:52
【问题描述】:

Couchdb 仅解析 application/x-www-form-urlencoded。是否有设置 enctype 的 FormData() 属性?

xhr.open('put',document.myForm.action,false)
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
xhr.send(new FormData(document.myForm))

【问题讨论】:

  • 你不会只是将 AJAX 请求中的 Content-Type 标头设置为 application/x-www-form-urlencoded 吗?如果您使用 jQuery,这是 $.ajax() 的默认 Content-Type 标头。如果您使用常规 XMLHttpRequest,则为 xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
  • 在 chrome 中它仍然会发送 multipart/form-data。
  • 您使用什么框架(如果有)来处理 AJAX 请求?
  • 不只是做 xhr.open('put',document.user.action,false) xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded') xhr .send(new FormData(document.user))
  • 好的,我还建议您使用 jquery.couch.js(位于 gert.iriscouch.com/_utils/script/jquery.couch.js)与您的 couchdb 进行交互。文档位于daleharvey.github.com/jquery.couch.js-docs/symbols/…

标签: javascript couchdb


【解决方案1】:

FormData 将始终以 multipart/form-data 发送。

如果您想以 x-www-form-urlencoded 的形式发送 FormData,请对内容项进行编码:

function urlencodeFormData(fd){
    var s = '';
    function encode(s){ return encodeURIComponent(s).replace(/%20/g,'+'); }
    for(var pair of fd.entries()){
        if(typeof pair[1]=='string'){
            s += (s?'&':'') + encode(pair[0])+'='+encode(pair[1]);
        }
    }
    return s;
}

var form = document.myForm;
xhr.open('POST', form.action, false);
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
xhr.send(urlencodeFormData(new FormData(form)));

你也可以像这样使用URLSearchParams

function urlencodeFormData(fd){
    var params = new URLSearchParams();
    for(var pair of fd.entries()){
        typeof pair[1]=='string' && params.append(pair[0], pair[1]);
    }
    return params.toString();
}

对于不支持URLSearchParams API 的旧浏览器,您可以使用其中一种 polyfill:

【讨论】:

  • MDN 说它不受 IE 和 Safari 的支持。此外,对此的支持需要相当高版本的其他浏览器:Chrome 49、Opera 36 和 Firefox 29(entries() 需要 Firefox 44):developer.mozilla.org/en/docs/Web/API/URLSearchParams
  • 有一些适用于不支持 URLSearchParams API 的旧浏览器的 polyfills
  • 我知道。这不是我的负面批评。我只是想指出,这种技术非常方便,但也很新。 :-)
  • 很高兴您似乎看过我的回答。 ;-)
  • @SteveOwens 如果要上传文件,您必须使用 multipart/form-data。
【解决方案2】:

不,XHR2 "send" method 被指定为始终将 FormData 对象作为 multipart/form-data 发送。

正如 & 号所暗示的,一种选择是使用内置于 Futon 内每个 CouchDB 实例中的 jquery.couch.js 插件。

如果你喜欢更通用的 HTTP 接口,Fermata 也支持 URL 编码请求:

fermata.json(document.myForm.action).put({'Content-Type':"application/x-www-form-urlencoded"}, {...form fields...});

另一种选择是将 JSON 发送到您的更新函数(我假设它是表单的“操作”URL)。

当然,其中任何一个的诀窍是您必须自己提取表单字段,因为没有简单的 DOM 级等价物 new FormData(document.myForm) 返回一个对象而不是 AFAIK。

【讨论】:

    【解决方案3】:

    这是一种更简单的方法,它不依赖于编写自己的转换:

     const form = document.getElementById('my_form')
     fetch(form.action,
           { headers: {'Content-Type': 'application/x-www-form-urlencoded'},
             body: new URLSearchParams(new FormData(form)) })
    

    它使用了URLSearchParams 构造函数可以接受FormData 对象(我认为可以迭代成对值的任何东西)并且fetch 知道将URLSearchParams 转换为字符串的事实。不过,您必须自己设置标题。

    【讨论】:

      【解决方案4】:

      前段时间我写了以下函数。它收集表单值并将它们编码为 url 编码,因此可以使用内容类型 application/x-www-form-urlencoded 发送它们:

      function getURLencodedForm(form)
      {
        var urlEncode = function(data, rfc3986)
        {
          if (typeof rfc3986 === 'undefined') {
            rfc3986 = true;
          }
      
          // Encode value
          data = encodeURIComponent(data);
          data = data.replace(/%20/g, '+');
      
          // RFC 3986 compatibility
          if (rfc3986)
          {
            data = data.replace(/[!'()*]/g, function(c) {
              return '%' + c.charCodeAt(0).toString(16);
            });
          }
      
          return data;
        };
      
        if (typeof form === 'string') {
          form = document.getElementById(form);
        }
      
        var url = [];
        for (var i=0; i < form.elements.length; ++i)
        {
          if (form.elements[i].name != '')
          {
            url.push(urlEncode(form.elements[i].name) + '=' + urlEncode(form.elements[i].value));
          }
        }
      
        return url.join('&');
      }
      
      // Example (you can test & execute this here on this page on stackoverflow)
      var url = getURLencodedForm('post-form');
      alert(url);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-04-29
        • 2016-09-07
        • 1970-01-01
        • 2018-10-19
        • 2014-05-19
        • 1970-01-01
        • 2019-01-03
        相关资源
        最近更新 更多