开发者

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

Couchd开发者_开发百科b only parse application/x-www-form-urlencoded. Is there a FormData() attribute that set the enctype?

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


FormData will always be sent as multipart/form-data.

If you just post normal form data without uploading files, multipart/form-data is better.

If you want to upload files, multipart/form-data is better.

If you have to upload files with x-www-form-urlencoded, you should convert the files data to string data via base64 etc, and write special server-end code. This is strongly not recommended.

If you want to send FormData as x-www-form-urlencoded, there are 2 ways at least.

1. Send URLSearchParams directly:

// 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. Encode the content items to querystring.

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)));

you can also use URLSearchParams like this:

function urlencodeFormData(fd){
    var params = new URLSearchParams(fd);
    return params.toString();
}

For old browsers which doesn't support URLSearchParams API, you can use one of polyfills:

  • ethanius / URLSearchParams
  • WebReflection / url-search-params


Here's a simpler way to do it that doesn't rely on writing your own conversions:

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

It uses the fact that the URLSearchParams constructor can accept a FormData object (anything that will iterate pairs of values, I think) and that fetch knows to convert URLSearchParams into a string and set the Content-Type header correctly.


No, the XHR2 "send" method is specified to always send FormData objects as multipart/form-data.

As ampersand suggests, one option would be to use the jquery.couch.js plugin that's built into every CouchDB instance within Futon.

If you like a bit more generic HTTP interface, Fermata also has support for URL encoded requests:

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

Another option would be to send JSON to your update function (which I'm assuming is the 'action' URL of your form) instead.

Of course, the trick with any of these is that you'll have to extract the form fields yourself, since there's no easy DOM-level equivalent of new FormData(document.myForm) that returns an Object instead AFAIK.


Some time ago I wrote the following function. It collects form values and encodes them url encoded, so they can be sent with content type 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);


Further building upon the response by @cmc and combining snippets from FormData API and Codemag's Fetch API tutorial, I use the following for a POST request that requires the Content-Type to be 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);
    });
});
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜