271 votes

Envoyer des données POST sans formulaire en JavaScript pur

Existe-t-il un moyen d'envoyer des données à l'aide de la méthode POST sans formulaire et sans rafraîchir la page en utilisant uniquement du JavaScript pur (pas de jQuery $.post() ) ? Il se peut que httprequest ou quelque chose d'autre (je ne le trouve pas pour l'instant) ?

4 votes

XMLHttpRequest est la réponse ... $.post utilise la même chose sous le capot.

0 votes

269voto

John G Points 1909

Vous pouvez l'envoyer et insérer les données dans le corps du message :

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

D'ailleurs, pour obtenir une demande :

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

4 votes

À quoi sert la variable booléenne true dans xhr.open ?

5 votes

3 votes

C'est l'ancienne façon de faire les demandes. Je recommande vivement de ne pas utiliser cette méthode et d'utiliser fetch à la place.

224voto

ContinuousLoad Points 1314

Les API Fetch est destiné à faciliter les requêtes GET, mais il est également capable d'effectuer des requêtes POST.

let data = {element: "barium"};

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

Si vous êtes aussi paresseux que moi (ou si vous préférez simplement un raccourci/une aide) :

window.post = function(url, data) {
  return fetch(url, {method: "POST", headers: {'Content-Type': 'application/json'}, body: JSON.stringify(data)});
}

// ...

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

4 votes

En raison de la simplicité de cette réponse, je l'ai votée prématurément et elle ne me permet pas de revenir sur mon vote. L'envoi de données ne fonctionne que si vous ajoutez des en-têtes. (headers : {'Accept' : 'application/json', 'Content-Type' : 'application/json'}) De plus, la réception de données ne fonctionne pas non plus à moins que vous n'appeliez la méthode json() sur la réponse, comme ceci : res.json(), qui renvoie encore une autre promesse que vous devez dérouler. Le mieux est d'utiliser async/await et de dérouler toutes ces promesses avec await.

1 votes

L'API "fetch" est la solution actuelle

0 votes

Merci, ça a marché comme sur des roulettes.

69voto

James Allardice Points 81162

Vous pouvez utiliser le XMLHttpRequest comme suit :

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

Ce code afficherait someStuff a url . Assurez-vous simplement que lorsque vous créez votre XMLHttpRequest il sera compatible avec tous les navigateurs. Il existe une multitude d'exemples de la manière de procéder.

2 votes

Pourriez-vous écrire un exemple pour someStuff ?

7 votes

SomeStuff = 'param1=val1&param2=val2&param3=val3'

1 votes

C'est une bonne réponse, et someStuff peut être ce que vous voulez, même une simple chaîne de caractères. Vous pouvez vérifier la demande en utilisant des services en ligne tels que mon préféré : ( requestb.in )

43voto

personal_cloud Points 862

De plus, RESTful vous permet d'obtenir des données retour d'un POST demande.

JS (placé dans static/hello.html pour servir via 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>

Serveur Python (pour les tests) :

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)

Journal de la console (chrome) :

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

Journal de la console (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 }

Journal de bord de la console (Edge) :

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"
      }
   }

Journal Python :

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

31voto

Desire Kaleba Points 850

Vous pouvez utiliser XMLHttpRequest, fetch API, ...

Si vous souhaitez utiliser XMLHttpRequest, vous pouvez procéder comme suit

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

Ou si vous souhaitez utiliser l'API de récupération

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X