Параметры данных формы jQuery Ajax преобразуются в чистый javascript

#javascript #jquery #ajax

Вопрос:

Нашел ответ благодаря Патрику Эвансу:

 window.onload = function()
{
    var data = new FormData();
    data.append("gcd", "gcd");
    data.append("name", "name");
    
    ajax({
        type: "POST",
        url: url,
        data: data,
        success: function(resopnse)
        {
            console.log(resopnse);
        },
        dataType: "json"
    });
}
var http_request = new XMLHttpRequest();
function ajax(options) {
    http_request.open(options.type || 'GET', options.url, true);
    http_request.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
    http_request.send(options.data || null);
    http_request.onreadystatechange = function() {
        if (http_request.readyState == 4) {
            if (http_request.status == 200) {
                var type = options.dataType || '';
                switch (type.toLowerCase()) {
                default: 
                    options.success(http_request.responseText);
                    break;
                case 'json': 
                    options.success(JSON.parse(http_request.responseText));
                    break;
                }
            }
        }
    }
}
 

Вот мой тестовый javascript Ajax с использованием jQuery и чистого Javascript Ajax:

 window.onload = function()
{
    var url = "GRNM";
    var data = {
        gcd: "gcd",
        name: "name"
    };
    
    $.ajax({
        type: "POST",
        url: url,
        data: data,
        success: function(resopnse)
        {
            console.log(resopnse);
        },
        dataType: "json"
    });
    
    ajax({
        type: "POST",
        url: url,
        data: data,
        success: function(resopnse)
        {
            console.log(resopnse);
        },
        dataType: "json"
    });
}
 

Чистый Javascript Ajax:

 var http_request = new XMLHttpRequest();
function ajax(options) {
    http_request.open(options.type || 'GET', options.url, true);
    http_request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
    http_request.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
    http_request.send(JSON.stringify(options.data) || null);
    http_request.onreadystatechange = function() {
        if (http_request.readyState == 4) {
            if (http_request.status == 200) {
                var type = options.dataType || '';
                switch (type.toLowerCase()) {
                default: 
                    options.success(http_request.responseText);
                    break;
                case 'json': 
                    options.success(JSON.parse(http_request.responseText));
                    break;
                }
            }
        }
    }
}
 

And this is the result:

jQuery: I could get the value data successfully

 General:
    Request URL: http://gaspc-011:8888/GRNM
    Request Method: POST
    Status Code: 200 
    Remote Address: 192.168.1.120:8888
    Referrer Policy: strict-origin-when-cross-origin
Response Headers:
    Connection: keep-alive
    Content-Length: 43
    Content-Type: application/json
    Date: Fri, 27 Aug 2021 06:20:37 GMT
    Keep-Alive: timeout=60
Request Headers:
    Accept: application/json, text/javascript, */*; q=0.01
    Accept-Encoding: gzip, deflate
    Accept-Language: en-US,en;q=0.9
    Connection: keep-alive
    Content-Length: 17
    Content-Type: application/x-www-form-urlencoded; charset=UTF-8
    Host: gaspc-011:8888
    Origin: http://gaspc-011:8888
    Referer: http://gaspc-011:8888/index01
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36
    X-Requested-With: XMLHttpRequest
Form Data:
    gcd: gcd
    name: name
 

Чистый Javascript: я не смог получить данные

 General:
    Request URL: http://gaspc-011:8888/GRNM
    Request Method: POST
    Status Code: 400 
    Remote Address: 192.168.1.120:8888
    Referrer Policy: strict-origin-when-cross-origin
Response Headers:
    Connection: close
    Content-Language: en-US
    Content-Type: text/html;charset=Shift_JIS
    Date: Fri, 27 Aug 2021 06:20:37 GMT
    Transfer-Encoding: chunked
Request Headers:
    Accept: */*
    Accept-Encoding: gzip, deflate
    Accept-Language: en-US,en;q=0.9
    Connection: keep-alive
    Content-Length: 27
    Content-Type: application/x-www-form-urlencoded; charset=UTF-8
    Host: gaspc-011:8888
    Origin: http://gaspc-011:8888
    Referer: http://gaspc-011:8888/index01
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36
    X-Requested-With: XMLHttpRequest
Form Data:
    {"gcd":"gcd","name":"name"}: 
 

Мой контроллер загрузки Spring не смог найти параметр gcd and name , полученный из чистого javascript, потому что формат данных формы отличается. Я также пытался использовать FormData() , но не смог заставить его работать.

Мои данные формы становятся такими:

 Form Data:
    ------WebKitFormBoundaryLgD8tjkxnVk4hfiE
    Content-Disposition: form-data; name: "gcd"

    gcd
    ------WebKitFormBoundaryLgD8tjkxnVk4hfiE
    Content-Disposition: form-data; name="name"

    name
    ------WebKitFormBoundaryLgD8tjkxnVk4hfiE--
 

Я также пытался переодеться http_request.send(JSON.stringify(options.data) || null); http_request.send(options.data || null); , но это не сработало.

Как я могу достичь того же результата, что и jQuery? Как я могу передать свой var data объект контроллеру, используя Ajax POST так же, как jQuery?

Комментарии:

1. Непонятно, о чем вы спрашиваете. Какой код вы использовали и какой код вы используете сейчас — пожалуйста, разделите ответ и объясните, что вам нужно от нас

2. @Teemu данные, которые контроллер не смог использовать, — это обычный JS.

3. Просто замените фигурные скобки пустыми строками.

4. Вы используете application/x-www-form-urlencoded тип содержимого для своего XMLHttpRequest , но вы предоставили ему текст в формате JSON, а не ожидаемую key=value строку параметров. Если вы используете FormData объект , то должен быть тип содержимого multipart/form-data , который автоматически устанавливается при использовании fetch или XMLHttpRequest , для jQuery вы должны установить processData и contentType false .

5. @mplungjan , мой вопрос в последней части

Ответ №1:

Вам необходимо указать правильный тип контента с правильным контентом.

Если вы хотите отправить текст в формате JSON, вам необходимо использовать application/json тип содержимого

 http_request.setRequestHeader('Content-Type', 'application/json');
http_request.send(JSON.stringify(options.data));
 

Если вы хотите использовать FormData объект, вам нужен multipart/form-data тип содержимого

 let fd = new FormData();
for(let key in options.data){
  fd.append(key,options.data[key]);
}
//don't need to explicitly set content-type when sending FormData
//it will automatically do that
//http_request.setRequestHeader('Content-Type', 'multipart/form-data');
http_request.send(fd);
 

Если вы просто хотите использовать свой объект, вам нужно будет преобразовать его в один из ранее упомянутых методов или создать из него строку параметров и использовать application/x-www-form-urlencoded тип содержимого

 //builds a param=valueamp;param2=value2 type of string from your options.data object
let paramStrings = [];
for(let key in options.data){
  paramStrings.push(`${key}=${options.data[key]}`);
}
let data = paramStrings.join('amp;');

http_request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
http_request.send(data);
 

Комментарии:

1. при использовании application/json контроллер загрузки Spring не смог прочитать параметр. Мои настройки контроллера: @PostMapping(value="GRNM") @ResponseBody public String GRNM(@RequestParam(name = "gcd") String gcd, @RequestParam String name) но FormData() это сработало, так что спасибо.