순수한 자바 스크립트 양식없이 POST 데이터 보내기


139

양식을 사용하지 않고 순수 자바 스크립트 (jQuery $.post()아님) 만 사용하여 페이지를 새로 고치지 않고 POST 메소드를 사용하여 데이터를 보내는 방법이 있습니까? 어쩌면 httprequest또는 다른 것이 있습니까? (지금은 찾을 수 없습니다)?


1
XMLHttpRequest는 대답입니다 ... $. post는 후드에서 동일하게 사용합니다.
Chandu

답변:


139

당신은 그것을 보내고 본문에 데이터를 삽입 할 수 있습니다 :

var xhr = new XMLHttpRequest();
xhr.open("POST", yourUrl, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify({
    value: value
}));

그건 그렇고, 요청을 얻으려면 :

var xhr = new XMLHttpRequest();
// we defined the xhr

xhr.onreadystatechange = function () {
    if (this.readyState != 4) return;

    if (this.status == 200) {
        var data = JSON.parse(this.responseText);

        // we get the returned data
    }

    // end of state change: it can be after some time (async)
};

xhr.open('GET', yourUrl, true);
xhr.send();

2
xhr.open의 실제 부울 변수는 무엇입니까?
Hylle


67

에서 [2017 년 작성시 새로운 틱] 가져 오기 API는 쉽게 GET 요청을하도록하지만, 잘으로 게시 할 수 있습니다.

let data = {element: "barium"};

fetch("/post/data/here", {
  method: "POST", 
  body: JSON.stringify(data)
}).then(res => {
  console.log("Request complete! response:", res);
});

나만큼 게으른 사람 (또는 바로 가기 / 도우미를 선호하는 경우) :

window.post = function(url, data) {
  return fetch(url, {method: "POST", body: JSON.stringify(data)});
}

// ...

post("post/data/here", {element: "osmium"});

54

XMLHttpRequest다음과 같이 객체를 사용할 수 있습니다 .

xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
xhr.send(someStuff);

해당 코드는에 게시 someStuff됩니다 url. XMLHttpRequest객체 를 만들 때 크로스 브라우저와 호환되는지 확인하십시오. 그것을하는 방법에 대한 끝없는 예가 있습니다.


1
당신은 예를 작성할 수 someStuff있습니까?
FluorescentGreen5 5

4
someStuff = 'PARAM1 = VAL1 & PARAM2 = val2만큼 & 3 당겨 = val3'
낙타

1
그것은 좋은 대답이며 someStuff간단한 문자열조차도 원하는 것이 될 수 있습니다. 내 개인적인 마음에 드는 것과 같은 온라인 서비스를 사용하여 요청을 확인할 수 있습니다 : ( requestb.in )
JamesC

application/x-www-form-urlencodedMIME 타입은 없습니다 charset매개 변수 : iana.org/assignments/media-types/application/...
JBG

28

또한 RESTful을 사용하면 POST 요청 에서 데이터를 다시 가져올 수 있습니다 .

JS (파이썬을 통해 제공하기 위해 static / hello.html에 입력) :

<html><head><meta charset="utf-8"/></head><body>
Hello.

<script>

var xhr = new XMLHttpRequest();
xhr.open("POST", "/postman", true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify({
    value: 'value'
}));
xhr.onload = function() {
  console.log("HELLO")
  console.log(this.responseText);
  var data = JSON.parse(this.responseText);
  console.log(data);
}

</script></body></html>

Python 서버 (테스트 용) :

import time, threading, socket, SocketServer, BaseHTTPServer
import os, traceback, sys, json


log_lock           = threading.Lock()
log_next_thread_id = 0

# Local log functiondef


def Log(module, msg):
    with log_lock:
        thread = threading.current_thread().__name__
        msg    = "%s %s: %s" % (module, thread, msg)
        sys.stderr.write(msg + '\n')

def Log_Traceback():
    t   = traceback.format_exc().strip('\n').split('\n')
    if ', in ' in t[-3]:
        t[-3] = t[-3].replace(', in','\n***\n***  In') + '(...):'
        t[-2] += '\n***'
    err = '\n***  '.join(t[-3:]).replace('"','').replace(' File ', '')
    err = err.replace(', line',':')
    Log("Traceback", '\n'.join(t[:-3]) + '\n\n\n***\n*** ' + err + '\n***\n\n')

    os._exit(4)

def Set_Thread_Label(s):
    global log_next_thread_id
    with log_lock:
        threading.current_thread().__name__ = "%d%s" \
            % (log_next_thread_id, s)
        log_next_thread_id += 1


class Handler(BaseHTTPServer.BaseHTTPRequestHandler):

    def do_GET(self):
        Set_Thread_Label(self.path + "[get]")
        try:
            Log("HTTP", "PATH='%s'" % self.path)
            with open('static' + self.path) as f:
                data = f.read()
            Log("Static", "DATA='%s'" % data)
            self.send_response(200)
            self.send_header("Content-type", "text/html")
            self.end_headers()
            self.wfile.write(data)
        except:
            Log_Traceback()

    def do_POST(self):
        Set_Thread_Label(self.path + "[post]")
        try:
            length = int(self.headers.getheader('content-length'))
            req   = self.rfile.read(length)
            Log("HTTP", "PATH='%s'" % self.path)
            Log("URL", "request data = %s" % req)
            req = json.loads(req)
            response = {'req': req}
            response = json.dumps(response)
            Log("URL", "response data = %s" % response)
            self.send_response(200)
            self.send_header("Content-type", "application/json")
            self.send_header("content-length", str(len(response)))
            self.end_headers()
            self.wfile.write(response)
        except:
            Log_Traceback()


# Create ONE socket.
addr = ('', 8000)
sock = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(addr)
sock.listen(5)

# Launch 100 listener threads.
class Thread(threading.Thread):
    def __init__(self, i):
        threading.Thread.__init__(self)
        self.i = i
        self.daemon = True
        self.start()
    def run(self):
        httpd = BaseHTTPServer.HTTPServer(addr, Handler, False)

        # Prevent the HTTP server from re-binding every handler.
        # https://stackoverflow.com/questions/46210672/
        httpd.socket = sock
        httpd.server_bind = self.server_close = lambda self: None

        httpd.serve_forever()
[Thread(i) for i in range(10)]
time.sleep(9e9)

콘솔 로그 (크롬) :

HELLO
hello.html:14 {"req": {"value": "value"}}
hello.html:16 
{req: {…}}
req
:
{value: "value"}
__proto__
:
Object

콘솔 로그 (firefox) :

GET 
http://XXXXX:8000/hello.html [HTTP/1.0 200 OK 0ms]
POST 
XHR 
http://XXXXX:8000/postman [HTTP/1.0 200 OK 0ms]
HELLO hello.html:13:3
{"req": {"value": "value"}} hello.html:14:3
Object { req: Object }

콘솔 로그 (가장자리) :

HTML1300: Navigation occurred.
hello.html
HTML1527: DOCTYPE expected. Consider adding a valid HTML5 doctype: "<!DOCTYPE html>".
hello.html (1,1)
Current window: XXXXX/hello.html
HELLO
hello.html (13,3)
{"req": {"value": "value"}}
hello.html (14,3)
[object Object]
hello.html (16,3)
   {
      [functions]: ,
      __proto__: { },
      req: {
         [functions]: ,
         __proto__: { },
         value: "value"
      }
   }

파이썬 로그 :

HTTP 8/postman[post]: PATH='/postman'
URL 8/postman[post]: request data = {"value":"value"}
URL 8/postman[post]: response data = {"req": {"value": "value"}}

8

를 사용하여 HTML 양식을 보내는 것처럼 데이터를 랩핑하여 서버로 보내는 쉬운 방법이 있습니다 POST. FormData다음과 같이 객체 를 사용하여 그렇게 할 수 있습니다 .

data = new FormData()
data.set('Foo',1)
data.set('Bar','boo')

let request = new XMLHttpRequest();
request.open("POST", 'some_url/', true);
request.send(data)

이제 Reugular HTML Forms를 다루는 것처럼 서버 측의 데이터를 처리 할 수 ​​있습니다.

추가 정보

브라우저가 처리하므로 FormData를 전송할 때 Content-Type 헤더를 설정하지 말 것을 권장합니다.


❗️는 FormData보다는 다중 양식 요청을 만들 것 application/x-www-form-urlencoded요청
ccpizza

@ccpizza-설명해 주셔서 감사합니다. OP는 POST 유형의 데이터 유형을 언급하지 않았기 때문에 FormData가 가장 적합한 답변 방법이라고 생각합니다.
Armin Hemati Nik

7

navigator.sendBeacon ()

단순히 POST데이터를 작성해야하고 서버의 응답이 필요하지 않은 경우 가장 짧은 해결책은 다음을 사용하는 것입니다 navigator.sendBeacon().

const data = JSON.stringify({
  example_1: 123,
  example_2: 'Hello, world!',
});

navigator.sendBeacon('example.php', data);

1
'Navigator'에서 'sendBeacon'을 실행하지 못했습니다. 비콘은 HTTP (S)를 통해서만 지원됩니다.
Ali80

navigator.sendBeacon내 의견으로는이 목적으로 사용되지 않습니다.
jolivier

5

XMLHttpRequest, fetch API 등

을 사용할 수 있습니다. XMLHttpRequest를 사용하려면 다음을 수행하십시오.

var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify({
    name: "Deska",
    email: "deska@gmail.com",
    phone: "342234553"
 }));
xhr.onload = function() {
    var data = JSON.parse(this.responseText);
    console.log(data);
};

또는 페치 API를 사용하려는 경우

fetch(url, {
    method:"POST",
    body: JSON.stringify({
        name: "Deska",
        email: "deska@gmail.com",
        phone: "342234553"
        })
    })
    .then(result => {
        // do something with the result
        console.log("Completed with result:", result);
    });

1

JavaScript에는 양식을 작성하고 제출하기위한 내장 메소드 및 라이브러리가 있다는 것을 알고 있습니까?

나는 여기에 많은 답장이 보이고, 나는 과도한 라이브러리라고 생각하는 타사 라이브러리를 사용하도록 요구하고 있습니다.

순수한 자바 스크립트에서 다음을 수행합니다.

<script>
function launchMyForm()
{
   var myForm = document.createElement("FORM");
   myForm.setAttribute("id","TestForm");
   document.body.appendChild(myForm);

// this will create a new FORM which is mapped to the Java Object of myForm, with an id of TestForm. Equivalent to: <form id="TestForm"></form>

   var myInput = document.createElement("INPUT");
   myInput.setAttribute("id","MyInput");
   myInput.setAttribute("type","text");
   myInput.setAttribute("value","Heider");
   document.getElementById("TestForm").appendChild(myInput);

// This will create an INPUT equivalent to: <INPUT id="MyInput" type="text" value="Heider" /> and then assign it to be inside the TestForm tags. 
}
</script>

이렇게하면 (A) 작업을 수행하기 위해 타사에 의존 할 필요가 없습니다. (B) 모든 브라우저에 내장되어 있으며 (C) 더 빠르며 (D) 작동하며 자유롭게 사용해보십시오.

이게 도움이 되길 바란다. H

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