简体   繁体   中英

Sending XMLHttpRequest with FormData

I am trying to make an XHR with JavaScript, but I can't get it to work correctly.

When I see the right requests in the "Network" tab of the Chrome developer tools I see that they have a "Form Data" section where are listed all the informations sent with the request, like this:

表单数据

Now, I've tried making my XMLHttpRequest in any way I know, but I can't get that result.

I have tried this:

var xhr = new XMLHttpRequest(),
    form_data = "data%5Btumblelog%5D=drunknight&data%5Bsource%5D=FOLLOW_SOURCE_REBLOG";
    // this is uri encoded: %5b = [ and %5D = ]

xhr.open('POST','https://www.somesite.com/page?' + form_data, false);
xhr.send();

But I got this "Query String Parameters" instead of "Form Data":

查询字符串参数

I have also tried this:

var xhr = new XMLHttpRequest(),
    formData = new FormData();

formData.append("data[tumblelog]", "drunknight");
formData.append("data[source]", "FOLLOW_SOURCE_REBLOG");
xhr.open('POST','https://www.somesite.com/page', false);
xhr.send(formData);

But I got this "Request Payload" instead of "Form Data":

有效负载

And, finally, I have tried this:

var xhr = new XMLHttpRequest(),
    formData = {
        "data[tumblelog]": "drunknight",
        "data[source]": "FOLLOW_SOURCE_REBLOG"
    };

xhr.open('POST','https://www.somesite.com/page', false);
xhr.send(JSON.stringify(formData));

But I got another "Request Payload" instead of "Form Data":

载荷2


Now, my question is: how can I send my XMLHttpRequest in order to obtain the same result as shown in the FIRST image?

You're missing the Content-Type header to specify that your data is form-like encoded.

This will work:

var xhr = new XMLHttpRequest(),
    data = "data%5Btumblelog%5D=drunknight&data%5Bsource%5D=FOLLOW_SOURCE_REBLOG";

xhr.open('POST','https://www.somesite.com/page', false);

// LINE ADDED
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

xhr.send(data);

EDIT

FormData is generally used to send binary data and will automatically set the Content-Type header to multipart/form-data (see FormData Spec and FormData Examples ). However you have to make sure the server also accepts request using this MIME-type, which apparently is not your case, as you already tried and it didn't work.

I noticed the OP tried using FormData in one of their iterations to solve the original problem.

I've recently started using the Fetch api for sending form data. It's designed with promises making it really easy to use (especially if there's a form to leverage for all of the inputs):

var form = document.forms[0];
var data = new FormData(form);
fetch(form.action, { method: form.method, body: data })
.then((response) => {
  // handle response
}).catch((error) => {
  // handle error
);

https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

Posting this as an answer because I believe it will give you exactly what you want to know;

I just want to know what sort of method is used to send that kind of data. I can assure you that the first image is obtained using an XHR

You haven't given enough information for us to see how the "correct" version is generated, but you can capture the relevant bits you want, drop in code like this before the working XMLHttpRequest is .open ed;

(function (obj, methods) {
    var i;
    function log() {
        console.log.apply(console, arguments);
    }
    for (i = 0; i < methods.length; ++i)
        obj[methods[i]] = (function (method_name, method) {
            return function () {
                log.call(null, method_name, arguments);
                return method.apply(this, arguments);
            }
        }(methods[i], obj[methods[i]]));
}(XMLHttpRequest.prototype, ['open', 'send', 'setRequestHeader']));

Now perform the action to make it fire and the relevant parameters will be logged so you can see exactly what happens to it as it is set up and sent, which should allow you to know what to pass into your one.


The problem is that I get a forbidden (403)

I'm going to assume this is not a same origin security-error because this looks server-returned and not a browser-initiated abort

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM