XMLHttpRequest를 사용하여 POST 데이터 보내기


526

JavaScript에서 XMLHttpRequest를 사용하여 데이터를 보내고 싶습니다.

HTML로 다음 양식이 있다고 가정 해보십시오.

<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에서 XMLHttpRequest를 사용하여 동등한 내용을 작성하려면 어떻게해야합니까?

답변:


748

아래 코드는이를 수행하는 방법을 보여줍니다.

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와 같은 문자열 대신 객체를 보낼 수 있습니까?
Vadorequest

4
아니요, 그러나 @Vadorequest의 의견은 jQuery를 언급했습니다. "jQuery와 같은"데이터를 전달할 수 있는지 물었습니다. jQuery가 어떻게 생각하는지, 그래서 어떻게 달성 할 수 있는지 언급했습니다.
Dan Pantry

11
@EdHeal ConnectionContent-Length헤더를 설정할 수 없습니다. "안전하지 않은 헤더"content-length "설정을 거부했습니다." 참조 stackoverflow.com/a/2624167/632951
Pacerier

76
참고 : setRequestHeader를 () 개방 (). 한 시간이 걸렸습니다.이 의견이 한 시간 동안 누군가를
Kevin

4
application/json요청 을 보낼 수 있습니까?

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');

또는 브라우저 지원을 기대할 수 있다면 FormData를 사용할 수 있습니다 .

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는 폼 요소를 생성자 인자로 취합니다. 개별적으로 값을 추가 할 필요가 없습니다
Juan Mendes

6
네, 그러나 질문은 제공된 양식과 동등한 JavaScript를 작성하여 JavaScript를 사용하여 양식을 제출하지 않는 것이 었습니다.
uKolka 2016 년

3
몇 표를 가지고 있지만 대답은 올바른 사용이 추가 헤더를 표시있어 : http.setRequestHeader("Content-length", params.length);http.setRequestHeader("Connection", "close");. 그들이 필요합니까? 그들은 아마도 특정 브라우저에서만 필요합니까? (다른 페이지에는 Content-Length 헤더를 설정하는 것이 "필요한 것"이라고 언급되어 있습니다.)
Darren Cook

@Darren Cook 구현에 따라 다릅니다. 필자의 경험에 따르면 주요 브라우저 는 제공하는 데이터에서 '콘텐츠 길이' (필수)를 자동 으로 설정합니다. 대부분의 경우 '연결' 헤더의 기본값은 '연결 유지'로 설정되어 잠시 동안 연결을 유지하므로 후속 요청은 '닫기'의 경우와 같이 연결을 다시 설정할 필요가 없습니다. 현재 페이지 URL을 사용하여 콘솔에서 해당 스 니펫을 시도하고 브라우저 도구 또는 wireshark를 사용하여 요청 헤더를 검사 할 수 있습니다.
uKolka

4
@uKolka 두 번째 솔루션보다 요청에 Content-Type자동으로 변경 되는 답장에 메모해야합니다 multipart/form-data. 이는 서버 측과 서버에 정보가 액세스되는 방식에 심각한 영향을 미칩니다.
AxeEffect

84

최신 JavaScript를 사용하십시오!

에서 살펴볼 것을 제안 fetch합니다. ES5와 동일하며 약속을 사용합니다. 훨씬 더 읽기 쉽고 쉽게 사용자 정의 할 수 있습니다.

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에서 다음을 fetch사용하여 가져와야합니다 .

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

동 기적으로 사용하려면 (상위 범위에서는 작동하지 않음) :

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

더 많은 정보:

모질라 문서

사용할 수 있습니까 (2020 년 3 월 95 %)

데이비드 월시 튜토리얼


4
많은 장치에 이러한 기능을 지원하는 브라우저가 없기 때문에 웹 페이지 기능에 중요한 사항에는 약속 및 굵은 화살표를 사용하지 않아야합니다.
Dmitry

8
약속 은 90 %가 보장됩니다. function()당신이 원하지 않는 경우 에 예제를 추가했습니다 =>. 개발자 경험을 쉽게하려면 최신 JS를 사용해야합니다. 소수의 사람들이 IE에 갇혀있는 것에 대해 걱정하는 것은 대기업이 아니라면 가치가 없습니다
Gibolt

4
지방 화살표는 this키워드 와도 작동하지 않습니다 . 나는 그것을 언급하고 싶지만 this함수 팩토리 대신 상속 아키텍처 를 사용하는 사람들을 은밀히 싫어 합니다. 용서하십시오, 나는 노드입니다.
agm1984

3
나는 this전염병처럼 피하기 때문에 누구나 읽을 것 this.
Gibolt

2
호환성이 걱정된다면 ... Google es6 트랜스 파일러 ... stackoverflow.com/questions/40205547/… . 간단하게 작성하십시오. 호환 가능하게 배치하십시오. +1 피하십시오 this.
TamusJRoyce

35

FormDataAJAX 요청 제출의 최소 사용

<!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>

비고

  1. 사용자가 요청을 제출하려면 클릭해야하므로 OP 질문에 완전히 답변하지는 않습니다. 그러나 이것은 이런 종류의 간단한 솔루션을 찾는 사람들에게 유용 할 수 있습니다.

  2. 이 예제는 매우 간단하며이 GET방법을 지원하지 않습니다 . 보다 정교한 예제로 흥미가 있다면 훌륭한 MDN 문서를 살펴보십시오 . HTMLHttpRequest to Post HTML Form에 대한 비슷한 답변 도 참조하십시오. .

  3. 이 솔루션의 한계 : Justin BlankThomas Munk (댓글 참조) FormData가 지적한 바와 같이 IE9 이하 및 Android 2.3의 기본 브라우저에서는 지원되지 않습니다.


1
이것에 대한 유일한 점은 IE 9에서는 FormData를 사용할 수 없다고 생각하므로 polyfill이없는 많은 사람들에게 사용할 수는 없습니다. developer.mozilla.org/en-US/docs/Web/API/FormData
Justin Blank

귀하의 링크에 대한 @ThomasMunk 감사합니다 :-) 우리는 FormDataIE9 및 Android 2.3 (및 OperaMini를 제외한 많은 브라우저에서 지원하지만이 마지막은 널리 사용되지 않음)을 참조하십시오. 건배 ;-)
olibre

2
우아한 솔루션이지만, onsubmit="return submitForm(this);"그렇지 않으면 사용자가 요청의 URL로 리디렉션되도록 지정해야합니다.
Vic

귀하의 기여에 감사드립니다. @Vic, 답변을 업데이트했습니다. 건배 ;-)
올리버

1
나는 웹 개발에 익숙하지 않다. POST 요청이 실제로 반환 할 때 전송되었다는 것을 알았습니다 false. 경우 true반환, 원래 (원치 않는) POST 요청이 전송 될 것입니다! 답이 맞습니다. 혼란을 드려 죄송합니다.
Markus L

30

다음은 완벽한 솔루션입니다 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>

백엔드 API가 JSON을 구문 분석 할 수 있는지 확인하십시오.

예를 들어, Express JS에서 :

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

1
훌륭하지만 XMLHttpRequest.open의 async 매개 변수에 'false'값을 사용하지 마십시오. 더 이상 사용되지 않으며 경고가 표시됩니다
johnnycardy

거기에 참을 두어야합니까 아니면 그 매개 변수를 생략해야합니까? 선호하는 것을 지정할 수 있으면 답변을 업데이트 할 것입니다.
agm1984

1
기본값은 true이지만 모든 브라우저가이를 존중하는지 모르겠습니다.
johnnycardy

기본값이 true이면 예제에서 제거하고 연구를 위해이 URL을 삭제합니다. developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/open
agm1984

1
나는 누군가가 시작하는 것이 합리적이고 하나의 세부 사항이 적기 때문에 더 좋아합니다. 강조해 주셔서 감사합니다.
agm1984

25

필요한 플러그인이 없습니다!

아래 코드를 선택하고 BOOKMARK BAR 에 끌어다 놓으십시오 ( 표시되지 않으면 브라우저 설정에서 활성화하십시오 ). 해당 링크 를 편집 하십시오.

여기에 이미지 설명을 입력하십시오

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);

그게 다야! 이제 모든 웹 사이트를 방문하고 BOOKMARK BAR 에서 해당 버튼을 클릭 할 수 있습니다 !


노트:

위의 방법은 방법을 사용하여 데이터를 전송 XMLHttpRequest하므로 스크립트를 트리거하는 동안 동일한 도메인에 있어야합니다. 그렇기 때문에 시뮬레이션 된 FORM SUBMITTING으로 데이터를 전송하는 것을 선호합니다.이 코드는 모든 도메인에 코드를 보낼 수 있습니다.

 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의 경우 이와 비슷한 작업을 수행 할 수 있습니까?

나는하지 못했습니다 : | 나는 125의 담당자가 없습니다 : | 내 프로필을 보면 136 표를 얻었습니다. | 공감할 수있는 권한을 얻은 후에도 필요한 경우가 아니면 피할 수 있습니다. |

18
그리고 귀하의 질문은 OP가 요청한 내용에 실제로 답변하지 않습니다. HTTP 요청 북마크하기 ...!? 관련 포인트가 보이지 않습니다XmlHttpRequest 당신의 대답 : |

2
대박. 답이 되었기 때문에 검토하면서 관계를 원했습니다. 이제이 질문에 대한 답은 gr8 팁입니다. 투표를 되돌 렸습니다. 건배
아이스 맨

5

같은 게시물을 사용하여 비슷한 문제에 직면 했으며이 링크를 사용하여 문제를 해결했습니다.

 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);

링크 는 정보를 완성했습니다.


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
안녕하세요 휴고,이 코드는 브라우저가 지원하는 경우 진행 업로드와 함께 데이터 또는 파일을 보내는 것입니다. 가능한 모든 이벤트 및 호환성 브라우저가 포함되었습니다. 브라우저에서 가장 새로운 객체 클래스를 사용해보십시오. 도움이 되셨습니까?
toto

2

formdata 대신 json 객체를 사용하십시오. 아래는 나를 위해 일하는 코드입니다. formdata도 나에게 도움이되지 않으므로이 솔루션을 생각해 냈습니다.

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

기능 독자가이 질문을 찾는 경우에만 해당됩니다. 주어진 경로가있는 한 받아 들인 대답이 제대로 작동한다는 것을 알았지 만 비워두면 IE에서 실패합니다. 다음은 내가 생각해 낸 것입니다.

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));
}

당신은 그렇게 할 수 있습니다 :

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

1

이것에 영향을 미치는 몇 가지 복제본이 있으며 아무도 그것에 대해 설명하지 않습니다. 설명을 위해 허용 된 답변 예제를 빌려 보겠습니다.

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

나는 설명을 위해 이것을 지나치게 단순화했다 (나는 http.onload(function() {})그 대답의 오래된 방법론 대신 사용한다 ). 이것을 그대로 사용하면 서버가 POST 본문을 실제 key=value매개 변수가 아닌 문자열로 해석하는 것입니다 (예 : PHP는 $_POST변수를 표시하지 않음 ). 그것을 얻으려면 양식 헤더를 전달 해야합니다.http.send()

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

URL 인코딩 데이터가 아닌 JSON을 사용하는 경우 application/json대신 전달하십시오.


1

이것은 xmlHttpRequest객체를 양식 데이터 로만 사용 하고 게시하고 싶을 때 도움이되었습니다 .

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.