问题
I’m sending a POST request via XMLHttpRequest
with data entered into an HTML form. The form without interference of JavaScript would submit its data encoded as application/x-www-form-urlencoded
.
With the XMLHttpRequest, I wanted to send the data with via the FormData
API which does not work since it treats the data as if it were encoded as multipart/form-data
. Therefor I need to write the data as a query string, properly escaped, into the send method of the 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();
});
Now this whole thing with the for ... of
loop, etc. seems a bit convoluted. Is there a simpler way to transform FormData
into a query string? Or can I somehow send FormData with a different encoding?
回答1:
You could use URLSearchParams
const queryString = new URLSearchParams(new FormData(myForm)).toString()
回答2:
You've asked for a simpler solution...
A for
loop is the simplest way to traverse over a collection - imho.
But there is a shorter version if you use the 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.
Your for...of
loop can then be replaced with:
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
回答3:
If you could use JQuery
, you'll simply call .serialize()
function on your form
object, like follow:
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>
Note: It also encode data for use it in url request
I hope it helps you, bye.
来源:https://stackoverflow.com/questions/42980645/easier-way-to-transform-formdata-into-query-string