XMLHttpRequest kullanarak POST verileri gönderme


526

JavaScript'te bir XMLHttpRequest kullanarak bazı veriler göndermek istiyorum.

Diyelim ki HTML'de şu form var:

<form name="inputform" action="somewhere" method="post">
    <input type="hidden" value="person" name="user">
    <input type="hidden" value="password" name="pwd">
    <input type="hidden" value="place" name="organization">
    <input type="hidden" value="key" name="requiredkey">
</form>

JavaScript'te XMLHttpRequest kullanarak eşdeğerini nasıl yazabilirim?

Yanıtlar:


748

Aşağıdaki kod, bunun nasıl yapılacağını gösterir.

var http = new XMLHttpRequest();
var url = 'get_data.php';
var params = 'orem=ipsum&name=binny';
http.open('POST', url, true);

//Send the proper header information along with the request
http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');

http.onreadystatechange = function() {//Call a function when the state changes.
    if(http.readyState == 4 && http.status == 200) {
        alert(http.responseText);
    }
}
http.send(params);

46
paramsJQuery gibi bir dize yerine bir nesne göndermek mümkün mü ?
Vadorequest

4
Hayır, ama @ Vadorequest'in yorumu jQuery'den bahsetti - verileri "jQuery gibi" iletmenin mümkün olup olmadığını sordu. Ben nasıl jQuery bunu düşünüyorum ve böylece, bunu nasıl başardı bahsetti.
Dan Pantry

11
@EdHeal Connectionve Content-Lengthbaşlıklar ayarlanamaz. "Güvenli olmayan başlık" içerik uzunluğu "" ayarını reddetti. Bkz. Stackoverflow.com/a/2624167/632951
Pacerier

76
Not: open () öğesinden sonra setRequestHeader (). Bana bir saat sürdü, umarım bu yorum bir saatte birini kurtarır;)
Kevin

4
application/jsonistek göndermek mümkün mü?

270
var xhr = new XMLHttpRequest();
xhr.open('POST', 'somewhere', true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.onload = function () {
    // do something to response
    console.log(this.responseText);
};
xhr.send('user=person&pwd=password&organization=place&requiredkey=key');

Veya tarayıcı desteğine güvenebiliyorsanız, FormData'yı kullanabilirsiniz :

var data = new FormData();
data.append('user', 'person');
data.append('pwd', 'password');
data.append('organization', 'place');
data.append('requiredkey', 'key');

var xhr = new XMLHttpRequest();
xhr.open('POST', 'somewhere', true);
xhr.onload = function () {
    // do something to response
    console.log(this.responseText);
};
xhr.send(data);

4
FormData form öğesini yapıcı argümanı olarak alır, bağımsız olarak değer eklemeye gerek yoktur
Juan Mendes

6
Evet, ancak soru, formun JavaScript kullanılarak gönderilmemesi için sağlanan formun JavaScript eşdeğerini yazmaktı.
uKolka

3
Çok az oyu olan ancak doğru işaretlenen cevap iki ekstra başlık kullanır: http.setRequestHeader("Content-length", params.length);ve http.setRequestHeader("Connection", "close");. İhtiyaçları var mı? Belki de sadece belirli tarayıcılarda gerekli midir? (Diğer sayfada, İçerik Uzunluğu başlığını ayarlamanın "tam olarak ne gerekiyordu" olduğunu belirten bir yorum var)
Darren Cook

@Darren Cook Uygulamaya bağlı. Deneyimlerime göre büyük tarayıcılar , sağladığınız verilerden otomatik olarak 'İçerik uzunluğu' ayarını (zorunludur) ayarlar . 'Bağlantı' başlığı varsayılan olarak 'canlı tut' şeklindedir, bu da bağlantıyı bir süre açık tutar, böylece sonraki istekler 'kapat' durumunda olduğu gibi bağlantıyı yeniden kurmak zorunda kalmaz. Geçerli sayfa URL'sini kullanarak bu snippet'leri konsolda deneyebilir ve tarayıcı araçlarını veya wireshark kullanarak istek başlıklarını inceleyebilirsiniz .
uKolka

4
@ uKolka cevabın, talebin Content-Typeotomatik olarak değiştiği ikinci çözümünüze göre not edilmesi gerekir multipart/form-data. Bunun sunucu tarafında ve bilgilere nasıl erişildiği üzerinde ciddi etkileri vardır.
AxeEffect

84

Modern JavaScript kullanın!

Bakmanızı öneririm fetch. ES5 eşdeğeri ve Promises kullanıyor. Çok daha okunabilir ve kolayca özelleştirilebilir.

const url = "http://example.com";
fetch(url, {
    method : "POST",
    body: new FormData(document.getElementById("inputform")),
    // -- or --
    // body : JSON.stringify({
        // user : document.getElementById('user').value,
        // ...
    // })
}).then(
    response => response.text() // .json(), etc.
    // same as function(response) {return response.text();}
).then(
    html => console.log(html)
);

Node.js'de şunları fetchkullanarak içe aktarmanız gerekir :

const fetch = require("node-fetch");

Senkronize olarak kullanmak istiyorsanız (üst kapsamda çalışmaz):

const json = await fetch(url, optionalOptions)
  .then(response => response.json()) // .text(), etc.
  .catch((e) => {});

Daha fazla bilgi:

Mozilla Belgeleri

Kullanabilir miyim (% 95 Mar 2020)

David Walsh Eğitimi


4
Pek çok cihazda bu özellikleri destekleyen tarayıcılar bulunmadığından, web sayfası işlevselliği açısından kritik öneme sahip şeyler için Vaatler ve şişman okları kullanmaktan kaçınmalısınız.
Dmitry

8
Vaatler % 90 oranındadır. function()Tercih etmemeniz durumunda örnekler ekledim =>. Geliştirici deneyimini kolaylaştırmak için kesinlikle modern JS kullanıyor olmalısınız. Eğer büyük bir girişim değilseniz IE üzerinde sıkışmış insanların küçük bir yüzdesi hakkında endişe değmez
Gibolt

4
Yağ oku da thisanahtar kelimeyle çalışmaz . Bundan bahsetmek isterim, ama aynı zamanda thisişlev fabrikaları yerine gizemli mimariyi kullanan insanlardan ve mirastan nefret ediyorum . Affet beni, ben düğümüm.
agm1984

3
thisVebadan da kaçınırım ve herkes okumalı this.
Gibolt

2
Uyumluluk konusunda endişeleriniz varsa ... Google es6 aktarıcısı ... stackoverflow.com/questions/40205547/… . Basit yaz. Uyumlu bir şekilde dağıtın. +1 kaçının this.
TamusJRoyce

35

FormDataAJAX isteği göndermek için asgari kullanım

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge, chrome=1"/>
<script>
"use strict";
function submitForm(oFormElement)
{
  var xhr = new XMLHttpRequest();
  xhr.onload = function(){ alert (xhr.responseText); } // success case
  xhr.onerror = function(){ alert (xhr.responseText); } // failure case
  xhr.open (oFormElement.method, oFormElement.action, true);
  xhr.send (new FormData (oFormElement));
  return false;
}
</script>
</head>

<body>
<form method="post" action="somewhere" onsubmit="return submitForm(this);">
  <input type="hidden" value="person"   name="user" />
  <input type="hidden" value="password" name="pwd" />
  <input type="hidden" value="place"    name="organization" />
  <input type="hidden" value="key"      name="requiredkey" />
  <input type="submit" value="post request"/>
</form>
</body>
</html>

Uyarılar

  1. Bu, OP sorusunu tam olarak yanıtlamaz, çünkü kullanıcının isteği göndermek için tıklamasını gerektirir. Ancak bu, bu tür basit bir çözüm arayan insanlar için yararlı olabilir.

  2. Bu örnek çok basittir ve GETyöntemi desteklemez . Daha sofistike örneklerle ilgileniyorsanız, lütfen mükemmel MDN belgelerine . XMLHttpRequest hakkında HTML Sonrası Form hakkında benzer yanıta da bakın .

  3. Bu çözümün sınırlandırılması: Justin Blank ve Thomas Munk tarafından belirtildiği gibi (yorumlarına bakın), FormDataIE9 ve altı ve Android 2.3'te varsayılan tarayıcı tarafından desteklenmemektedir.


1
Bununla ilgili tek şey, FormData'nın IE 9'da mevcut olmadığını düşünüyorum, bu yüzden çok dolgu olmayan birçok insan için kullanılabilir olmayacak. developer.mozilla.org/tr-TR/docs/Web/API/FormData
Justin Blank

Bağlantınız için teşekkürler @ThomasMunk :-) Bunun FormDataIE9 ve Android 2.3 hariç birçok tarayıcı tarafından desteklendiğini görüyoruz (ve OperaMini ancak bu son yaygın olarak kullanılmıyor). Şerefe ;-)
olibre

2
Zarif bir çözüm, ancak onsubmit="return submitForm(this);"aksi takdirde kullanıcının istekte URL'ye yönlendirileceğini belirtmelisiniz .
Vic

Katkılarınız için @Vic'e teşekkürler, cevabı güncelledim. Şerefe ;-)
olibre

1
Web geliştirme konusunda deneyimli değilim. Ben döndüğünüzde POST isteği gerçekten gönderildi anladım false. trueİade edilirse , orijinal (istenmeyen) POST isteği gönderilecektir! Cevabınız doğru, karışıklık için özür dileriz.
Markus L

30

İşte tam bir çözüm application-json:

// Input values will be grabbed by ID
<input id="loginEmail" type="text" name="email" placeholder="Email">
<input id="loginPassword" type="password" name="password" placeholder="Password">

// return stops normal action and runs login()
<button onclick="return login()">Submit</button>

<script>
    function login() {
        // Form fields, see IDs above
        const params = {
            email: document.querySelector('#loginEmail').value,
            password: document.querySelector('#loginPassword').value
        }

        const http = new XMLHttpRequest()
        http.open('POST', '/login')
        http.setRequestHeader('Content-type', 'application/json')
        http.send(JSON.stringify(params)) // Make sure to stringify
        http.onload = function() {
            // Do whatever with response
            alert(http.responseText)
        }
    }
</script>

Arka Uç API'nizin JSON'u ayrıştırabildiğinden emin olun.

Örneğin, Express JS'de:

import bodyParser from 'body-parser'
app.use(bodyParser.json())

1
Harika, ancak XMLHttpRequest.open içindeki async parametresi için 'false' değeri kullanmayın - kullanımdan kaldırılmıştır ve bir uyarı verecektir
johnnycardy

Oraya doğru koymalı mıyız yoksa sadece bu parametreyi mi atlamalıyız? Hangisinin tercih edileceğini belirtebilirseniz cevabı güncelleyeceğim.
agm1984

1
Varsayılan olarak doğru olmalıdır, ancak tüm tarayıcıların buna saygı
gösterip

True varsayılanı göz önüne alındığında, onu örnekten kaldıracağım ve araştırma için bu URL'yi bırakacağım: developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/open
agm1984

1
Bunu daha iyi seviyorum çünkü makul ve birinin başlaması için daha az ayrıntı. Vurguladığınız için teşekkürler.
agm1984

25

FİŞE GEREK YOK!

Aşağıdaki kodu seçin ve BOOKMARK BAR içine sürükleyin ( görmüyorsanız, Tarayıcı Ayarları'ndan etkinleştirin ), sonra bu bağlantıyı DÜZENLEYİN :

resim açıklamasını buraya girin

javascript:var my_params = prompt("Enter your parameters", "var1=aaaa&var2=bbbbb"); var Target_LINK = prompt("Enter destination", location.href); function post(path, params) { var xForm = document.createElement("form"); xForm.setAttribute("method", "post"); xForm.setAttribute("action", path); for (var key in params) { if (params.hasOwnProperty(key)) { var hiddenField = document.createElement("input"); hiddenField.setAttribute("name", key); hiddenField.setAttribute("value", params[key]); xForm.appendChild(hiddenField); } } var xhr = new XMLHttpRequest(); xhr.onload = function () { alert(xhr.responseText); }; xhr.open(xForm.method, xForm.action, true); xhr.send(new FormData(xForm)); return false; } parsed_params = {}; my_params.split("&").forEach(function (item) { var s = item.split("="), k = s[0], v = s[1]; parsed_params[k] = v; }); post(Target_LINK, parsed_params); void(0);

Bu kadar! Şimdi herhangi bir web sitesini ziyaret edebilir ve BOOKMARK BAR'da bu düğmeyi tıklayabilirsiniz !


NOT:

Yukarıdaki yöntem yöntemi kullanarak veri gönderir XMLHttpRequest, bu nedenle komut dosyasını tetiklerken aynı etki alanında olmanız gerekir. Bu nedenle, kodu herhangi bir alana gönderebilen simüle edilmiş bir FORM SUBMITTING ile veri göndermeyi tercih ediyorum - işte bunun için kod:

 javascript:var my_params=prompt("Enter your parameters","var1=aaaa&var2=bbbbb"); var Target_LINK=prompt("Enter destination", location.href); function post(path, params) {   var xForm= document.createElement("form");   xForm.setAttribute("method", "post");   xForm.setAttribute("action", path); xForm.setAttribute("target", "_blank");   for(var key in params) {   if(params.hasOwnProperty(key)) {        var hiddenField = document.createElement("input");      hiddenField.setAttribute("name", key);      hiddenField.setAttribute("value", params[key]);         xForm.appendChild(hiddenField);     }   }   document.body.appendChild(xForm);  xForm.submit(); }   parsed_params={}; my_params.split("&").forEach(function(item) {var s = item.split("="), k=s[0], v=s[1]; parsed_params[k] = v;}); post(Target_LINK, parsed_params); void(0); 

Mozilla için buna benzer bir şey yapabilir miyim?

Yapmadım ve yapamadım: | 125 temsilcim yok: | Ve eğer profilimi görürsen göreceğim 136 oy var: | Ben downvote izni aldıktan sonra bile, gerekli olmadığı sürece ben kaçınacaktır: |

18
Ve sorunuz OP'nin ne istediğine gerçekten cevap vermiyor. Bir HTTP İsteğini Park Etme ...!? XmlHttpRequestCevabınızla ilgili herhangi bir nokta görmüyorum : |

2
müthiş. sadece bir cevap olduğu için gözden geçirirken biraz ilişki istedim. şimdi bir cevap artı herkes tarafından gr8 ipucu. Oyları geri aldım. alkış
Iceman

5

Aynı yazıyı kullanarak benzer bir sorunla karşılaştım ve bu bağlantı sorunumu çözdüm.

 var http = new XMLHttpRequest();
 var url = "MY_URL.Com/login.aspx";
 var params = 'eid=' +userEmailId+'&amp;pwd='+userPwd

 http.open("POST", url, true);

 // Send the proper header information along with the request
 //http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
 //http.setRequestHeader("Content-Length", params.length);// all browser wont support Refused to set unsafe header "Content-Length"
 //http.setRequestHeader("Connection", "close");//Refused to set unsafe header "Connection"

 // Call a function when the state 
 http.onreadystatechange = function() {
    if(http.readyState == 4 && http.status == 200) {
        alert(http.responseText);
    }
 }
 http.send(params);

Bu bağlantı bilgileri tamamladı.


4
var util = {
    getAttribute: function (dom, attr) {
        if (dom.getAttribute !== undefined) {
            return dom.getAttribute(attr);
        } else if (dom[attr] !== undefined) {
            return dom[attr];
        } else {
            return null;
        }
    },
    addEvent: function (obj, evtName, func) {
        //Primero revisar attributos si existe o no.
        if (obj.addEventListener) {
            obj.addEventListener(evtName, func, false);

        } else if (obj.attachEvent) {
            obj.attachEvent(evtName, func);
        } else {
            if (this.getAttribute("on" + evtName) !== undefined) {
                obj["on" + evtName] = func;
            } else {
                obj[evtName] = func;
            }

        }

    },
    removeEvent: function (obj, evtName, func) {
        if (obj.removeEventListener) {
            obj.removeEventListener(evtName, func, false);
        } else if (obj.detachEvent) {
            obj.detachEvent(evtName, func);
        } else {
            if (this.getAttribute("on" + evtName) !== undefined) {
                obj["on" + evtName] = null;
            } else {
                obj[evtName] = null;
            }
        }

    },
    getAjaxObject: function () {
        var xhttp = null;
        //XDomainRequest
        if ("XMLHttpRequest" in window) {
            xhttp = new XMLHttpRequest();
        } else {
            // code for IE6, IE5
            xhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
        return xhttp;
    }

};

//START CODE HERE.

var xhr = util.getAjaxObject();

var isUpload = (xhr && ('upload' in xhr) && ('onprogress' in xhr.upload));

if (isUpload) {
    util.addEvent(xhr, "progress", xhrEvt.onProgress());
    util.addEvent(xhr, "loadstart", xhrEvt.onLoadStart);
    util.addEvent(xhr, "abort", xhrEvt.onAbort);
}

util.addEvent(xhr, "readystatechange", xhrEvt.ajaxOnReadyState);

var xhrEvt = {
    onProgress: function (e) {
        if (e.lengthComputable) {
            //Loaded bytes.
            var cLoaded = e.loaded;
        }
    },
    onLoadStart: function () {
    },
    onAbort: function () {
    },
    onReadyState: function () {
        var state = xhr.readyState;
        var httpStatus = xhr.status;

        if (state === 4 && httpStatus === 200) {
            //Completed success.
            var data = xhr.responseText;
        }

    }
};
//CONTINUE YOUR CODE HERE.
xhr.open('POST', 'mypage.php', true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');


if ('FormData' in window) {
    var formData = new FormData();
    formData.append("user", "aaaaa");
    formData.append("pass", "bbbbb");

    xhr.send(formData);

} else {

    xhr.send("?user=aaaaa&pass=bbbbb");
}

1
Merhaba Hugo, Bu kod, tarayıcı destekliyorsa veri yüklemesi ile veri veya dosya göndermek içindir. tüm olası olayları ve uyumluluk tarayıcısını içerir. Tarayıcıdan en yeni nesne sınıfını kullanmayı deneyin. Size yardımcı olur mu?
toto

2

Formdata yerine json nesnesini kullanmaya çalışın. aşağıda benim için çalışan kod. formdata da benim için çalışmıyor, bu yüzden bu çözümü buldum.

var jdata = new Object();
jdata.level = levelVal; // level is key and levelVal is value
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "http://MyURL", true);
xhttp.setRequestHeader('Content-Type', 'application/json');
xhttp.send(JSON.stringify(jdata));

xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      console.log(this.responseText);
    }
}

1

Sadece bu soruyu bulan özellik okuyucuları için. Kabul edilen cevabın, belirli bir yolunuz olduğu sürece iyi çalıştığını buldum, ancak boş bırakırsanız IE'de başarısız olacaktır. İşte ben geldim:

function post(path, data, callback) {
    "use strict";
    var request = new XMLHttpRequest();

    if (path === "") {
        path = "/";
    }
    request.open('POST', path, true);
    request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
    request.onload = function (d) {
        callback(d.currentTarget.response);
    };
    request.send(serialize(data));
}

Bunu şöyle yapabilirsiniz:

post("", {orem: ipsum, name: binny}, function (response) {
    console.log(respone);
})

1

Buna dokunan bazı kopyalar var ve kimse bunu gerçekten açıklamıyor. Kabul etmek için kabul edilen cevap örneğini ödünç alacağım

http.open('POST', url, true);
http.send('lorem=ipsum&name=binny');

http.onload(function() {})Örnekleme amacıyla bunu ( bu cevabın eski metodolojisi yerine kullanıyorum) aşırı basitleştirdim . Bunu olduğu gibi kullanırsanız, sunucunuzun POST gövdesini gerçek key=valueparametreler olarak değil, bir dize olarak yorumladığını görürsünüz (yani PHP herhangi bir $_POSTdeğişken göstermez ). Sen gerekir o olsun form başlığını geçmek ve daha önce bunuhttp.send()

http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');

URL kodlu verileri değil JSON kullanıyorsanız, application/jsonbunun yerine geçin


1

Bu sadece bana kullanmak xmlHttpRequestve form verisi olarak bir nesne göndermek istedim bana yardımcı oldu :

function sendData(data) {
  var XHR = new XMLHttpRequest();
  var FD  = new FormData();

  // Push our data into our FormData object
  for(name in data) {
    FD.append(name, data[name]);
  }

  // Set up our request
  XHR.open('POST', 'https://example.com/cors.php');

  // Send our FormData object; HTTP headers are set automatically
  XHR.send(FD);
}

https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.