new FormData() "application/x-www-form-urlencoded"

问题描述 投票:0回答:5

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))
javascript couchdb
5个回答
29
投票

FormData 将始终作为

multipart/form-data
.

发送

如果只是发普通的表单数据,不上传文件,

multipart/form-data
比较好

如果要上传文件,

multipart/form-data
比较好

如果必须使用

x-www-form-urlencoded
上传文件,需要将文件数据通过base64等方式转换为字符串数据,并编写专门的服务端代码。强烈不建议这样做。

如果你想发送 FormData 为

x-www-form-urlencoded
,至少有两种方式。

1。直接发送URLSearchParams

// use xhr API
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
xhr.send(new URLSearchParams(formDataObj));

// or use fetch API
fetch(url, {
    method: 'post',
    body: new URLSearchParams(formDataObj)
});

2。将内容项编码为查询字符串。

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(fd);
    return params.toString();
}

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


22
投票

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

 const form = document.getElementById('my_form')
 fetch(form.action,
       { body: new URLSearchParams(new FormData(form)) })

它使用了这样一个事实,即

URLSearchParams
构造函数可以接受一个
FormData
对象(我认为任何会迭代值对的对象)并且
fetch
知道将
URLSearchParams
转换为字符串并设置 Content-Type标题正确。


8
投票

不,XHR2“发送”方法被指定为始终将FormData对象作为多部分/表单数据发送。

如 & 号所示,一种选择是使用内置于 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。


0
投票

前段时间写了下面这个函数。它收集表单值并将它们编码为 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);

0
投票

进一步构建@cmc 的响应并结合FormData APICodemag 的Fetch API 教程 的片段,我将以下内容用于需要

POST
Content-Type
application/x-www-form-urlencoded
请求:

const form = document.forms.namedItem("my_form");
form.addEventListener("submit", (event) => {
  event.preventDefault();
  fetch(form.action, {
    method: "POST",
    body: new URLSearchParams(new FormData(form)),
  })
    .then((response) => {
      if (response.ok) {
        return response.json();
      } else {
        return response.text();
      }
    })
    .then((data) => displayMessage(JSON.stringify(data)))
    .catch((error) => {
      console.error("Error: ", error);
    });
});
© www.soinside.com 2019 - 2024. All rights reserved.