[英]Pure JavaScript Send POST Data Without a Form
有沒有辦法在沒有表單的情況下使用 POST 方法發送數據,並且只使用純 JavaScript(不是 jQuery $.post()
)刷新頁面? 也許是httprequest
或其他東西(只是現在找不到)?
您可以發送它並將數據插入正文:
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();
[2017 年撰寫本文時的新版本] Fetch API旨在簡化 GET 請求,但它也能夠 POST。
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"});
您可以按如下方式使用XMLHttpRequest
對象:
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
xhr.send(someStuff);
該代碼會將someStuff
發布到url
。 只需確保在創建XMLHttpRequest
對象時,它將是跨瀏覽器兼容的。 有無數的例子來說明如何做到這一點。
此外,REST風格讓你從一個POST請求的數據備份。
JS(放入 static/hello.html 以通過 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>
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
控制台日志(火狐):
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"
}
}
Python日志:
HTTP 8/postman[post]: PATH='/postman'
URL 8/postman[post]: request data = {"value":"value"}
URL 8/postman[post]: response data = {"req": {"value": "value"}}
您可以使用 XMLHttpRequest、獲取 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);
};
或者如果你想使用 fetch 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);
}).catch(err => {
// if any error occured, then catch it here
console.error(err);
});
有一種簡單的方法可以包裝數據並將其發送到服務器,就像使用POST
發送 HTML 表單一樣。 您可以使用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)
現在您可以像處理常規 HTML 表單一樣在服務器端處理數據。
附加信息
建議您在發送 FormData 時不要設置 Content-Type 標頭,因為瀏覽器會處理這些。
如果您只需要POST
數據並且不需要來自服務器的響應,最短的解決方案是使用navigator.sendBeacon()
:
const data = JSON.stringify({
example_1: 123,
example_2: 'Hello, world!',
});
navigator.sendBeacon('example.php', data);
您是否知道 JavaScript 具有創建表單和提交表單的內置方法和庫?
我在這里看到很多回復都要求使用 3rd 方庫,我認為這有點矯枉過正。
我會在純 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) 你不需要依賴 3rd 方來完成這項工作。 (B) 所有瀏覽器都內置了它,(C) 更快,(D) 它可以工作,請隨意嘗試。
我希望這有幫助。 H
const data = { username: 'example' };
fetch('https://example.com/profile', {
method: 'POST', // or 'PUT'
headers: {
' Content-Type': 'application/json',
},
body: JSON.stringify(data),
})
.then(response => response.json())
.then(data => {
console.log('Success:', data);
})
.catch((error) => {
console.error('Error:', error);
});
這里最流行的答案沒有顯示如何從 POST 取回數據。 此外,當將數據發送到最新版本的 NodeJS 時,流行的“獲取”解決方案在最新版本的 Chrome 中不起作用,除非您傳遞標頭並解開 response.json() 承諾。 此外,流行的答案不使用 async/await。
這是我能想出的最干凈、最完整的解決方案。
async function postJsonData(jsonObject) {
const response = await fetch("/echo", {
method: "POST",
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(jsonObject)
});
const actualResponse = await response.json();
}
這是您(或其他任何人)可以在他們的代碼中使用的一個很好的函數:
function post(url, data) {
return new Promise((res, rej) => {
let stringified = "";
for (const [key, value] of Object.entries(data))
stringified += `${stringified != '' ? '&' : ''}${key}=${value}`
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState == 4)
if (xhr.status == 200)
res(xhr.responseText)
else
rej({ code: xhr.status, text: xhr.responseText })
}
xhr.open("POST", url, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(stringified);
})
}
使用 jbezz 庫的這個函數
var makeHttpObject = function () {
try {return new XMLHttpRequest();}
catch (error) {}
try {return new ActiveXObject("Msxml2.XMLHTTP");}
catch (error) {}
try {return new ActiveXObject("Microsoft.XMLHTTP");}
catch (error) {}
throw new Error("Could not create HTTP request object.");
}
function SendData(data){
let type = (data.type ? data.type : "GET")
let DataS = data.data;
let url = data.url;
let func = (data.success ? data.success : function(){})
let funcE =(data.error ? data.error : function(){})
let a_syne = (data.asyne ? data.asyne : false);
let u = null;
try{u = new URLSearchParams(DataS).toString();}catch(e){u = Object.keys(DataS).map(function(k) {return encodeURIComponent(k) + '=' + encodeURIComponent(DataS[k])}).join('&')}
if(type == "GET"){url +="?"+u}
const xhttp = makeHttpObject();
xhttp.onload = function(){func(this.responseText)}
xmlHttp.onreadystatechange = function() {if (xmlHttp.readyState == 4)
{if(xmlHttp.status !== 200){funcE(xmlHttp.statusText)}}}
xhttp.open(type,url,a_syne);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send(u);
}
使用它來運行:
SendData({
url:"YOUR_URL",
asyne:true,
type:"POST", // or GET
data:{
username:"ali",
password:"mypass" // Your Data
},
success:function(Result){
console.log(Result)
},
error:function(e){
console.log("We Have Some Error")
}
});
或者
下載jbezz
並添加到您的頁面。
下載鏈接: github.com
用 :
$$.api({
url:"YOUR_URL",
asyne:true,
type:"POST", // or GET
data:{
username:"ali",
password:"mypass" // Your Data
},
success:function(Result){
console.log(Result)
},
error:function(e){
console.log("We Have Some Error")
}
});
你也可以使用這個: https : //github.com/floscodes/JS/blob/master/Requests.js
您可以輕松發送 http-Request。 只需使用:
HttpRequest("https://example.com", method="post", data="yourkey=yourdata");
而已! 如果站點受 CSRF 保護,它甚至應該可以工作。
或者只是使用發送 GET-Request
HttpRequest("https://example.com", method="get");
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.