将 FormData 转换为查询字符串的更简单方法

Easier way to transform FormData into query string

我正在通过 XMLHttpRequest 发送 POST 请求,并将数据输入 HTML 表格。不受 JavaScript 干扰的表单将提交编码为 application/x-www-form-urlencoded.

的数据

使用 XMLHttpRequest,我想通过 FormData API 发送数据,但这不起作用,因为它将数据视为编码为 multipart/form-data。因此,我需要将数据作为查询字符串写入 XMLHttpRequest.

的发送方法中,并正确转义
addEntryForm.addEventListener('submit', function(event) {
    // Gather form data
    var formData = new FormData(this);
    // Array to store the stringified and encoded key-value-pairs.
    var parameters = []
    for (var pair of formData.entries()) {
        parameters.push(
            encodeURIComponent(pair[0]) + '=' +
            encodeURIComponent(pair[1])
        );
    }

    var httpRequest = new XMLHttpRequest();
    httpRequest.open(form.method, form.action);

    httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

    httpRequest.onreadystatechange = function() {
        if (httpRequest.readyState === XMLHttpRequest.DONE) {
            if (httpRequest.status === 200) {
                console.log('Successfully submitted the request');
            } else {
                console.log('Error while submitting the request');
            }
        }
    };

    httpRequest.send(parameters.join('&'));

    // Prevent submitting the form via regular request
    event.preventDefault();
});

现在,for ... of 循环等整个事情看起来有点令人费解。有没有更简单的方法将 FormData 转换为查询字符串?或者我可以以某种方式发送具有不同编码的 FormData 吗?

如果您可以使用 JQuery,您只需在 form 对象上调用 .serialize() 函数,如下所示:

function getQueryString() {
  var str = $( "form" ).serialize();
  console.log(str);
}

$( "#cmdTest" ).on( "click", getQueryString );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<form>
  <select name="list1">
    <option>opt1</option>
    <option>opt2</option>
  </select>
 
  <br>
  <input type="text" name="txt1" value="valWith%Special&Char$">
  <br>
  <input type="checkbox" name="check" value="check1" id="ch1">
  <label for="ch1">check1</label>
  <input type="checkbox" name="check" value="check2" checked="checked" id="ch2">
  <label for="ch2">check2</label>
 
  <br>
  <input type="radio" name="radio" value="radio1" checked="checked" id="r1">
  <label for="r1">radio1</label>
  <input type="radio" name="radio" value="radio2" id="r2">
  <label for="r2">radio2</label>
</form>
  
<button id="cmdTest">Get queryString</button>

注意:它还对数据进行编码以便在 url 请求

中使用

希望对你有帮助,再见

您要求的是更简单的解决方案...
for 循环是遍历集合的最简单方法 - 恕我直言。

但是如果你使用 spread operator/syntax (...)

会有一个更短的版本

The spread syntax allows an expression to be expanded in places where multiple arguments (for function calls) or multiple elements (for array literals) or multiple variables (for destructuring assignment) are expected.

您的 for...of 循环可以替换为:

let parameters = [...formData.entries()] // expand the elements from the .entries() iterator into an actual array
                     .map(e => encodeURIComponent(e[0]) + "=" + encodeURIComponent(e[1]))  // transform the elements into encoded key-value-pairs

你可以使用 URLSearchParams

const queryString = new URLSearchParams(new FormData(myForm)).toString()