Có cách nào để gửi dữ liệu bằng phương thức POST mà không cần biểu mẫu và không làm mới trang chỉ bằng JavaScript thuần túy (không phải jQuery $.post()
) không? Có thể httprequest
hoặc một cái gì đó khác (không thể tìm thấy nó bây giờ)?
Có cách nào để gửi dữ liệu bằng phương thức POST mà không cần biểu mẫu và không làm mới trang chỉ bằng JavaScript thuần túy (không phải jQuery $.post()
) không? Có thể httprequest
hoặc một cái gì đó khác (không thể tìm thấy nó bây giờ)?
Câu trả lời:
Bạn có thể gửi nó và chèn dữ liệu vào phần thân:
var xhr = new XMLHttpRequest();
xhr.open("POST", yourUrl, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify({
value: value
}));
Nhân tiện, để nhận yêu cầu:
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();
[New-ish tại thời điểm viết vào năm 2017] API tìm nạp nhằm mục đích làm cho các yêu cầu GET trở nên dễ dàng, nhưng nó cũng có thể POST.
let data = {element: "barium"};
fetch("/post/data/here", {
method: "POST",
body: JSON.stringify(data)
}).then(res => {
console.log("Request complete! response:", res);
});
Nếu bạn lười như tôi (hoặc chỉ thích một phím tắt / người trợ giúp):
window.post = function(url, data) {
return fetch(url, {method: "POST", body: JSON.stringify(data)});
}
// ...
post("post/data/here", {element: "osmium"});
Bạn có thể sử dụng XMLHttpRequest
đối tượng như sau:
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
xhr.send(someStuff);
Mã đó sẽ được đăng someStuff
lên url
. Chỉ cần đảm bảo rằng khi bạn tạo XMLHttpRequest
đối tượng của mình , nó sẽ tương thích với nhiều trình duyệt. Có những ví dụ bất tận về cách làm điều đó.
someStuff
?
someStuff
có thể là bất cứ điều gì bạn muốn ngay cả một chuỗi đơn giản. bạn có thể kiểm tra yêu cầu bằng các dịch vụ trực tuyến như mục yêu thích cá nhân của tôi: ( requestb.in )
application/x-www-form-urlencoded
loại MIME không có một charset
tham số: iana.org/assignments/media-types/application/...
Ngoài ra, RESTful cho phép bạn lấy lại dữ liệu từ yêu cầu POST .
JS (đặt tĩnh / hello.html để phân phát qua Python):
<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>
Máy chủ Python (để thử nghiệm):
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)
Nhật ký bảng điều khiển (chrome):
HELLO
hello.html:14 {"req": {"value": "value"}}
hello.html:16
{req: {…}}
req
:
{value: "value"}
__proto__
:
Object
Nhật ký bảng điều khiển (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 }
Nhật ký bảng điều khiển (Cạnh):
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"
}
}
Nhật ký Python:
HTTP 8/postman[post]: PATH='/postman'
URL 8/postman[post]: request data = {"value":"value"}
URL 8/postman[post]: response data = {"req": {"value": "value"}}
Có một phương pháp dễ dàng để bọc dữ liệu của bạn và gửi nó đến máy chủ như thể bạn đang gửi một biểu mẫu HTML bằng cách sử dụng POST
. bạn có thể làm điều đó bằng cách sử dụng FormData
đối tượng như sau:
data = new FormData()
data.set('Foo',1)
data.set('Bar','boo')
let request = new XMLHttpRequest();
request.open("POST", 'some_url/', true);
request.send(data)
bây giờ bạn có thể xử lý dữ liệu ở phía máy chủ giống như cách bạn xử lý các Biểu mẫu HTML được giới thiệu lại.
Thông tin bổ sung
Bạn không nên đặt tiêu đề Kiểu nội dung khi gửi FormData vì trình duyệt sẽ đảm nhiệm việc đó.
FormData
sẽ tạo ra một yêu cầu hình thức nhiều phần dữ liệu chứ không phải là một application/x-www-form-urlencoded
yêu cầu
Nếu bạn chỉ cần POST
dữ liệu và không yêu cầu phản hồi từ máy chủ, giải pháp ngắn nhất sẽ là sử dụng navigator.sendBeacon()
:
const data = JSON.stringify({
example_1: 123,
example_2: 'Hello, world!',
});
navigator.sendBeacon('example.php', data);
navigator.sendBeacon
theo ý kiến của tôi không được sử dụng cho mục đích này.
Bạn có thể sử dụng XMLHttpRequest, tìm nạp API, ...
Nếu bạn muốn sử dụng XMLHttpRequest, bạn có thể làm như sau
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);
};
Hoặc nếu bạn muốn sử dụng API tìm nạp
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);
});
Bạn có biết rằng JavaScript có các phương thức và lib được tích hợp sẵn để tạo biểu mẫu và gửi chúng không?
Tôi đang thấy rất nhiều câu trả lời ở đây, tất cả đều yêu cầu sử dụng thư viện của bên thứ 3 mà tôi nghĩ là quá mức cần thiết.
Tôi sẽ làm như sau trong Javascript thuần túy:
<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>
Bằng cách này (A) bạn không cần phải dựa vào bên thứ 3 để thực hiện công việc. (B) Tất cả được tích hợp sẵn cho tất cả các trình duyệt, (C) nhanh hơn, (D) nó hoạt động, thoải mái dùng thử.
Tôi hi vọng cái này giúp được. H