Jak powstaje żądanie HTTP POST w node.js?

946

Jak mogę wysłać wychodzące żądanie HTTP POST z danymi w pliku node.js?

znak
źródło
16
Jak zasugerowano w odpowiedzi Jed Watsona , zdecydowanie polecam użycie żądania, chyba że piszesz niskopoziomowy interfejs API.
namuol
4
Możesz po prostu użyć node-fetchimplementacji natywnej fetchmetody JavaScript do wysyłania żądań HTTP.
Fez Vrasta,
Ten post dotyczy podstawowych scenariuszy użycia żądania. blog.modulus.io/node.js-tutorial-how-to-use-request-module
Shaswat Rungta

Odpowiedzi:

855

Oto przykład użycia node.js do wysłania żądania POST do interfejsu API Google Compiler:

// We need this to build our post string
var querystring = require('querystring');
var http = require('http');
var fs = require('fs');

function PostCode(codestring) {
  // Build the post string from an object
  var post_data = querystring.stringify({
      'compilation_level' : 'ADVANCED_OPTIMIZATIONS',
      'output_format': 'json',
      'output_info': 'compiled_code',
        'warning_level' : 'QUIET',
        'js_code' : codestring
  });

  // An object of options to indicate where to post to
  var post_options = {
      host: 'closure-compiler.appspot.com',
      port: '80',
      path: '/compile',
      method: 'POST',
      headers: {
          'Content-Type': 'application/x-www-form-urlencoded',
          'Content-Length': Buffer.byteLength(post_data)
      }
  };

  // Set up the request
  var post_req = http.request(post_options, function(res) {
      res.setEncoding('utf8');
      res.on('data', function (chunk) {
          console.log('Response: ' + chunk);
      });
  });

  // post the data
  post_req.write(post_data);
  post_req.end();

}

// This is an async file read
fs.readFile('LinkedList.js', 'utf-8', function (err, data) {
  if (err) {
    // If this were just a small part of the application, you would
    // want to handle this differently, maybe throwing an exception
    // for the caller to handle. Since the file is absolutely essential
    // to the program's functionality, we're going to exit with a fatal
    // error instead.
    console.log("FATAL An error occurred trying to read in the file: " + err);
    process.exit(-2);
  }
  // Make sure there's data before we post it
  if(data) {
    PostCode(data);
  }
  else {
    console.log("No data to post");
    process.exit(-1);
  }
});

Zaktualizowałem kod, aby pokazać, jak wysyłać dane z pliku, zamiast ciągu zakodowanego na stałe. W tym celu wykorzystuje fs.readFilekomendę async , umieszczając rzeczywisty kod po udanym odczycie. Jeśli wystąpi błąd, jest on zgłaszany, a jeśli nie ma żadnych danych, proces kończy się wartością ujemną, wskazując na błąd.

onteria_
źródło
4
Czy nagłówek długości treści jest obliczany poprawnie? Niby bajty, prawda?
Eric,
7
Pamiętaj, że querystring.stringify() nie obsługuje zagnieżdżonych obiektów , więc możesz użyć qs.stringify()zamiast tego.
johndodo,
51
Content-Lengthto bajty i niekoniecznie długość łańcucha (UTF-16 itp.). Używanie Buffer.byteLength(data)zawsze będzie poprawne.
greenimpala
4
do wysyłania standardowych danych pocztowych obiekt querystring.stringifypowinien być twoim własnym obiektem danych, a nie śmieciami wyświetlanymi w tej odpowiedzi (co może być przydatne w przypadku obiektów opartych na plikach?).
Utknąłem
7
Gotcha: Jeśli korzystasz z witryny zaszyfrowanej ssl, potrzebujesz biblioteki „https”. Nie możesz po prostu zmienić portu na 443.
Dave Collins
1137

Jest to o wiele łatwiejsze, jeśli korzystasz z biblioteki żądań .

var request = require('request');

request.post(
    'http://www.yoursite.com/formpage',
    { json: { key: 'value' } },
    function (error, response, body) {
        if (!error && response.statusCode == 200) {
            console.log(body);
        }
    }
);

Oprócz zapewnienia ładnej składni sprawia, że ​​żądania JSS są łatwe, obsługuje automatyczne podpisywanie (dla Twittera itp.), Może wykonywać formularze wieloczęściowe (np. Do przesyłania plików) i strumieniować.

Aby zainstalować żądanie, użyj polecenia npm install request

Jed Watson
źródło
153
{formularz: {klucz: „wartość”}} należy zastąpić {json: {klucz: „wartość”}} (ponieważ pytanie nie jest specyficzne dla formularzy). Trzeba też zrozumieć, że „forma” i „json” są słowami kluczowymi biblioteki żądań, a nie częścią niestandardowych danych (tak trywialne, jak może się wydawać ten ostatni komentarz, zajęło mi to trochę czasu, aby je zrozumieć ...)
blacelle
7
Wracam do tego pytania i odpowiedzi. To naprawdę powinna być „odpowiedź” na pytanie.
Spencer Kormos,
6
Zasługujesz na złotą odznakę wyłącznie za tę odpowiedź. Jest o wiele bardziej przydatny niż zaakceptowany ... i istniał już w 2012 roku? Wow
Zoltán Schmidt
3
może być konieczne dodanie zależności, uruchamiając polecenie „instalacja npm - zapisanie żądania”
Shady Sherif
18
Ta biblioteka jest przestarzała.
Evorlor
138

Możesz użyć biblioteki żądań. https://www.npmjs.com/package/request

var request = require('request');

Aby opublikować dane JSON:

var myJSONObject = { ... };
request({
    url: "http://josiahchoi.com/myjson",
    method: "POST",
    json: true,   // <--Very important!!!
    body: myJSONObject
}, function (error, response, body){
    console.log(response);
});

Aby opublikować dane XML:

var myXMLText = '<xml>...........</xml>'
request({
    url: "http://josiahchoi.com/myjson",
    method: "POST",
    headers: {
        "content-type": "application/xml",  // <--Very important!!!
    },
    body: myXMLText
}, function (error, response, body){
    console.log(response);
});
Josiah Choi
źródło
Po przejrzeniu w ich dokumentacji. stwierdza, co następuje: json - ustawia treść, ale do reprezentacji wartości JSON i dodaje Content-type: application / json header. Dodatkowo analizuje treść odpowiedzi jako JSON. Oznacza to, że gdy json = true, ustawi nagłówek, json i treść. W przeciwnym razie nagłówek nie zostanie ustawiony i parsowany jako tekst. (Podobnie jak w powyższym przykładzie XML). To sprawia, że ​​interfejs API żądania jest wygodny i uproszczony, ale trudny do zrozumienia za pierwszym razem.
Josiah Choi,
Technicznie jest to w ich dokumentach, ale żaden z przykładów tego nie pokazuje - tylko dane z formularza. To igła w stogu siana, i jako taka, jest to ogromna komisja, ponieważ jest to drugi najczęstszy sposób, w jaki używam ajax w JS, i na pewno jeden z najczęstszych w sieci.
Kyle Baker,
Użycie request.post jest IMO nieco lepsze niż określenie POST jako metody. Oto kilka przykładów z GitHub na użycie request.post
drorw
12
Ta biblioteka jest przestarzała.
Evorlor
44

Używam Restlera i Igły do celów produkcyjnych. Oba są znacznie potężniejsze niż natywny httprequest. Możliwe jest żądanie podstawowego uwierzytelnienia, specjalnego wpisu w nagłówku, a nawet przesyłania / pobierania plików.

Jeśli chodzi o operację post / get, są one również znacznie prostsze w użyciu niż surowe wywołania ajax przy użyciu httprequest.

needle.post('https://my.app.com/endpoint', {foo:'bar'}, 
    function(err, resp, body){
        console.log(body);
});
Grant Li
źródło
Wypróbowałem żądanie, dane formularza węzła i superagenta przed igłą. igła była jedyną, która działała dla mnie poprawnie podczas próby przesłania pliku wieloczęściowego.
Paul Young,
35

Prosty i bez zależności. Wykorzystuje obietnicę, abyś mógł poczekać na wynik. Zwraca treść odpowiedzi i nie sprawdza kodu statusu odpowiedzi.

const https = require('https');

function httpsPost({body, ...options}) {
    return new Promise((resolve,reject) => {
        const req = https.request({
            method: 'POST',
            ...options,
        }, res => {
            const chunks = [];
            res.on('data', data => chunks.push(data))
            res.on('end', () => {
                let body = Buffer.concat(chunks);
                switch(res.headers['content-type']) {
                    case 'application/json':
                        body = JSON.parse(body);
                        break;
                }
                resolve(body)
            })
        })
        req.on('error',reject);
        if(body) {
            req.write(body);
        }
        req.end();
    })
}

Stosowanie:

const res = await httpsPost({
    hostname: 'sentry.io',
    path: `/api/0/organizations/org/releases/${changesetId}/deploys/`,
    headers: {
        'Authorization': `Bearer ${process.env.SENTRY_AUTH_TOKEN}`,
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        environment: isLive ? 'production' : 'demo',
    })
})
mpen
źródło
Do czego służy writemetoda req,write()?
Ari
@Ari That pisze treść wniosku ... nodejs.org/api/…
mpen
21

Możesz także użyć Requestify , naprawdę fajnego i prostego klienta HTTP, który napisałem dla nodeJS +, który obsługuje buforowanie.

Po prostu wykonaj następujące czynności:

    var requestify = require('requestify');

    requestify.post('http://example.com', {
        hello: 'world'
    })
    .then(function(response) {
        // Get the response body (JSON parsed or jQuery object for XMLs)
        response.getBody();
    });
ranm8
źródło
1
Dla mnie to nie działa, patrz problem tutaj: github.com/ranm8/requestify/issues/2
Erel Segal-Halevi
20

Aktualizacja 2020:

Bardzo lubię phin - ultralekki klient HTTP Node.js

Można go używać na dwa różne sposoby. Jedna z obietnicami (Async / Await), a druga z tradycyjnymi stylami wywołania zwrotnego.

Zainstaluj przez: npm i phin

Prosto z README dzięki await:

const p = require('phin')

await p({
    url: 'https://ethanent.me',
    method: 'POST',
    data: {
        hey: 'hi'
    }
})


Styl bez reklam (oddzwanianie):

const p = require('phin').unpromisified

p('https://ethanent.me', (err, res) => {
    if (!err) console.log(res.body)
})

Począwszy od 2015 r. Istnieje obecnie wiele różnych bibliotek, które mogą to osiągnąć przy minimalnym kodowaniu. Wolę eleganckie i lekkie biblioteki do żądań HTTP, chyba że absolutnie potrzebujesz kontroli nad niskopoziomowymi rzeczami HTTP.

Jedną z takich bibliotek jest Unirest

Aby go zainstalować, użyj npm.
$ npm install unirest

I na Hello, World!przykładzie, do którego wszyscy są przyzwyczajeni.

var unirest = require('unirest');

unirest.post('http://example.com/helloworld')
.header('Accept', 'application/json')
.send({ "Hello": "World!" })
.end(function (response) {
  console.log(response.body);
});


Dodatkowo:
wiele osób sugeruje również użycie żądania [2]

Warto zauważyć, że za kulisami Unirestkorzysta z requestbiblioteki.

Unirest zapewnia metody bezpośredniego dostępu do obiektu żądania.

Przykład:

var Request = unirest.get('http://mockbin.com/request');
Levi Roberts
źródło
1
Kolejnym, który okazał się całkiem niezły, jest github.com/request/request, który wydaje się być nieco bardziej popularny niż unirest, przynajmniej w chwili pisania tego
tekstu
Mogę zaświadczyć na żądanie. To bardzo dobra biblioteka. Uważam, że to żądanie zapewnia więcej funkcji niskiego poziomu, więc należy go używać do określonych aplikacji. Kiedy niekoniecznie dbam o rzeczy niskiego poziomu, uważam, że Unirest jest odpowiedni.
Levi Roberts
Dlaczego unirest miałby być uważany za lekki, gdy zależy to od żądania? Samo żądanie ma 22 zależności, nie rozumiem, jak to jest lekkie
raphadko
@raphadko Jestem pewien, że z biegiem lat pojawiła się funkcja wzdęcia. Sprawdź znacznik czasu, kiedy opublikowałem swoją odpowiedź;)
Levi Roberts,
17
var https = require('https');


/**
 * HOW TO Make an HTTP Call - POST
 */
// do a POST request
// create the JSON object
jsonObject = JSON.stringify({
    "message" : "The web of things is approaching, let do some tests to be ready!",
    "name" : "Test message posted with node.js",
    "caption" : "Some tests with node.js",
    "link" : "http://www.youscada.com",
    "description" : "this is a description",
    "picture" : "http://youscada.com/wp-content/uploads/2012/05/logo2.png",
    "actions" : [ {
        "name" : "youSCADA",
        "link" : "http://www.youscada.com"
    } ]
});

// prepare the header
var postheaders = {
    'Content-Type' : 'application/json',
    'Content-Length' : Buffer.byteLength(jsonObject, 'utf8')
};

// the post options
var optionspost = {
    host : 'graph.facebook.com',
    port : 443,
    path : '/youscada/feed?access_token=your_api_key',
    method : 'POST',
    headers : postheaders
};

console.info('Options prepared:');
console.info(optionspost);
console.info('Do the POST call');

// do the POST call
var reqPost = https.request(optionspost, function(res) {
    console.log("statusCode: ", res.statusCode);
    // uncomment it for header details
//  console.log("headers: ", res.headers);

    res.on('data', function(d) {
        console.info('POST result:\n');
        process.stdout.write(d);
        console.info('\n\nPOST completed');
    });
});

// write the json data
reqPost.write(jsonObject);
reqPost.end();
reqPost.on('error', function(e) {
    console.error(e);
});
Giulio Roggero
źródło
czy istnieje sposób, aby wyświetlić treść postu z prośbą lub odpowiedzią?
jacoballenwood,
17

Dostępnych jest wiele bibliotek typu open source, których można użyć do utworzenia żądania HTTP POST w węźle.

1. Axios (zalecane)

const axios = require('axios');

const data = {
    name: 'John Doe',
    job: 'Content Writer'
};

axios.post('https://reqres.in/api/users', data)
    .then((res) => {
        console.log(`Status: ${res.status}`);
        console.log('Body: ', res.data);
    }).catch((err) => {
        console.error(err);
    });

2. Igła

const needle = require('needle');

const data = {
    name: 'John Doe',
    job: 'Content Writer'
};

needle('post', 'https://reqres.in/api/users', data, {json: true})
    .then((res) => {
        console.log(`Status: ${res.statusCode}`);
        console.log('Body: ', res.body);
    }).catch((err) => {
        console.error(err);
    });

3. Wniosek

const request = require('request');

const options = {
    url: 'https://reqres.in/api/users',
    json: true,
    body: {
        name: 'John Doe',
        job: 'Content Writer'
    }
};

request.post(options, (err, res, body) => {
    if (err) {
        return console.log(err);
    }
    console.log(`Status: ${res.statusCode}`);
    console.log(body);
});

4. Natywny moduł HTTPS

const https = require('https');

const data = JSON.stringify({
    name: 'John Doe',
    job: 'Content Writer'
});

const options = {
    hostname: 'reqres.in',
    path: '/api/users',
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'Content-Length': data.length
    }
};


const req = https.request(options, (res) => {
    let data = '';

    console.log('Status Code:', res.statusCode);

    res.on('data', (chunk) => {
        data += chunk;
    });

    res.on('end', () => {
        console.log('Body: ', JSON.parse(data));
    });

}).on("error", (err) => {
    console.log("Error: ", err.message);
});

req.write(data);
req.end();

Aby uzyskać szczegółowe informacje, sprawdź ten artykuł .

attacomsian
źródło
14

Jest to najprostszy sposób, w jaki wykonuję żądanie: używając modułu „request”.

Polecenie instalacji modułu „prośba”:

$ npm install request

Przykładowy kod:

var request = require('request')

var options = {
  method: 'post',
  body: postData, // Javascript object
  json: true, // Use,If you are sending JSON data
  url: url,
  headers: {
    // Specify headers, If any
  }
}

request(options, function (err, res, body) {
  if (err) {
    console.log('Error :', err)
    return
  }
  console.log(' Body :', body)

});

Możesz również użyć wbudowanego modułu „http” Node.js, aby wysłać zapytanie.

Piyush Sagar
źródło
1
Ta biblioteka jest przestarzała.
Jurij Tkachenko
12

Podoba mi się prostota superagenta ( https://github.com/visionmedia/superagent ). Ten sam interfejs API w węźle i przeglądarce.

;(async function() {
  var response = await superagent.post('http://127.0.0.1:8125/', {age: 2})
  console.log(response)
})

Istnieje również funkcja pobierania węzłów ( https://www.npmjs.com/package/node-fetch ), która ma interfejs API zgodny fetchz przeglądarkami - wymaga to jednak ręcznego kodowania ciągu zapytań, nie obsługuje automatycznie typów treści lub tak robi każdy inny superagent pracy.

Pascal Belloncle
źródło
1
I w przeciwieństwie do igły, unirestu i kooperatora, zapewnia lekkość (superagent: 16 tys., Unirest: 1 mln, igła: 530 tys.)
Lars,
9

Jeśli szukasz żądań HTTP opartych na obietnicach, axios dobrze sobie radzi.

  const axios = require('axios');

  axios.post('/user', {firstName: 'Fred',lastName: 'Flintstone'})
      .then((response) => console.log(response))
      .catch((error) => console.log(error));

LUB

await axios.post('/user', {firstName: 'Fred',lastName: 'Flintstone'})
Pujan Srivastava
źródło
6

Aby
wysłać żądanie Rest / JSON Możemy po prostu użyć pakietu żądania i zapisać wartości, które musimy wysłać w zmiennej Json.

Najpierw zainstaluj wymagany pakiet w konsoli, wysyłając np. Żądanie instalacji npm - zapisz

var request = require('request');

    var options={
                'key':'28',
                'key1':'value',
                'key2':'value'
                }

    request({
             url:"http://dev.api.ean.com/ean-services/rs/hotel/v3/ping?                      
                 minorRev="+options.key+
                 "&cid="+options.key1+
                 "&apiKey="+options.key2,
             method:"POST",
             json:true},function(error,response,body){
                     console.log(body)
               }
    );
Prakhar Sharma
źródło
2
Nigdy nie twórz własnego ciągu zapytania. Zaniedbujesz prawidłowe kodowanie swoich wartości. Node.js ma bibliotekę do tego celu: nodejs.org/api/querystring.html
Brad
Ta biblioteka jest przestarzała.
Jurij Tkachenko
4

Znalazłem film, który wyjaśnia, jak to osiągnąć: https://www.youtube.com/watch?v=nuw48-u3Yrg

Wykorzystuje domyślny moduł „http” wraz z modułami „querystring” i „stringbuilder”. Aplikacja pobiera dwie liczby (używając dwóch pól tekstowych) ze strony internetowej i po przesłaniu zwraca sumę tych dwóch (wraz z utrwaleniem wartości w polach tekstowych). To najlepszy przykład, jaki mogłem znaleźć gdziekolwiek indziej.

var http = require("http");
var qs = require("querystring");
var StringBuilder = require("stringbuilder");

var port = 9000;

function getCalcHtml(req, resp, data) {
    var sb = new StringBuilder({ newline: "\r\n" });
    sb.appendLine("<html>");
    sb.appendLine(" <body>");
    sb.appendLine("     <form method='post'>");
    sb.appendLine("         <table>");
    sb.appendLine("             <tr>");
    sb.appendLine("                 <td>Enter First No: </td>");

    if (data && data.txtFirstNo) {
        sb.appendLine("                 <td><input type='text' id='txtFirstNo' name='txtFirstNo' value='{0}'/></td>", data.txtFirstNo);
    }
    else {
        sb.appendLine("                 <td><input type='text' id='txtFirstNo' name='txtFirstNo' /></td>");
    }

    sb.appendLine("             </tr>");
    sb.appendLine("             <tr>");
    sb.appendLine("                 <td>Enter Second No: </td>");

    if (data && data.txtSecondNo) {
        sb.appendLine("                 <td><input type='text' id='txtSecondNo' name='txtSecondNo' value='{0}'/></td>", data.txtSecondNo);
    }
    else {
        sb.appendLine("                 <td><input type='text' id='txtSecondNo' name='txtSecondNo' /></td>");
    }

    sb.appendLine("             </tr>");
    sb.appendLine("             <tr>");
    sb.appendLine("                 <td><input type='submit' value='Calculate' /></td>");
    sb.appendLine("             </tr>");

    if (data && data.txtFirstNo && data.txtSecondNo) {
        var sum = parseInt(data.txtFirstNo) + parseInt(data.txtSecondNo);
        sb.appendLine("             <tr>");
        sb.appendLine("                 <td>Sum: {0}</td>", sum);
        sb.appendLine("             </tr>");
    }

    sb.appendLine("         </table>");
    sb.appendLine("     </form>")
    sb.appendLine(" </body>");
    sb.appendLine("</html>");
    sb.build(function (err, result) {
        resp.write(result);
        resp.end();
    });
}

function getCalcForm(req, resp, data) {
    resp.writeHead(200, { "Content-Type": "text/html" });
    getCalcHtml(req, resp, data);
}

function getHome(req, resp) {
    resp.writeHead(200, { "Content-Type": "text/html" });
    resp.write("<html><html><head><title>Home</title></head><body>Want to some calculation? Click <a href='/calc'>here</a></body></html>");
    resp.end();
}

function get404(req, resp) {
    resp.writeHead(404, "Resource Not Found", { "Content-Type": "text/html" });
    resp.write("<html><html><head><title>404</title></head><body>404: Resource not found. Go to <a href='/'>Home</a></body></html>");
    resp.end();
}

function get405(req, resp) {
    resp.writeHead(405, "Method not supported", { "Content-Type": "text/html" });
    resp.write("<html><html><head><title>405</title></head><body>405: Method not supported</body></html>");
    resp.end();
}

http.createServer(function (req, resp) {
    switch (req.method) {
        case "GET":
            if (req.url === "/") {
                getHome(req, resp);
            }
            else if (req.url === "/calc") {
                getCalcForm(req, resp);
            }
            else {
                get404(req, resp);
            }
            break;
        case "POST":
            if (req.url === "/calc") {
                var reqBody = '';
                req.on('data', function (data) {
                    reqBody += data;
                    if (reqBody.length > 1e7) { //10MB
                        resp.writeHead(413, 'Request Entity Too Large', { 'Content-Type': 'text/html' });
                        resp.end('<!doctype html><html><head><title>413</title></head><body>413: Request Entity Too Large</body></html>');
                    }
                });
                req.on('end', function () {
                    var formData = qs.parse(reqBody);
                    getCalcForm(req, resp, formData);
                });
            }
            else {
                get404(req, resp);
            }
            break;
        default:
            get405(req, resp);
            break;
    }
}).listen(port);
użytkownik203687
źródło
4

To moje rozwiązanie dla POSTi GET.

O Postmetodzie:

Jeśli ciało jest obiektem JSON, ważne jest, aby dokonać deserializacji za pomocą JSON.stringifyi ewentualnie odpowiednio ustawić Content-Lenghtnagłówek:

      var bodyString=JSON.stringify(body)
      var _headers = {
        'Content-Length': Buffer.byteLength(bodyString)
      };

przed napisaniem go do zapytania:

request.write( bodyString );

O obu Geti Postmetod:

timeoutMoże występować jako socketrozłączeniem, więc należy zarejestrować swój obsługi takiego:

request.on('socket', function (socket) {
        socket.setTimeout( self.timeout );
        socket.on('timeout', function() {
            request.abort();
            if(timeout) return timeout( new Error('request timed out') );
        });
    });

podczas gdy requestmoduł obsługi jest

       request.on('timeout', function () {
          // Timeout happend. Server received request, but not handled it
          // (i.e. doesn't send any response or it took to long).
          // You don't know what happend.
          // It will emit 'error' message as well (with ECONNRESET code).
          req.abort();
          if(timeout) return timeout( new Error('request timed out') );
        });

Zdecydowanie sugeruję zarejestrowanie obu programów obsługi.

Ciało odpowiedzi jest podzielone na części, dlatego należy połączyć elementy w module dataobsługi:

      var body = '';
      response.on('data', function(d) {
          body += d;
      });

Na będą zawierać całe ciało odpowiedzi:endbody

      response.on('end', function() {
        try {
            var jsonResponse=JSON.parse(body);
            if(success) return success( jsonResponse );
        } catch(ex) { // bad json
          if(error) return error(ex.toString());
        }
      });

Można bezpiecznie zawinąć za pomocą try... catch theJSON.parse`, ponieważ nie można być pewnym, że jest to dobrze sformatowany plik json i nie ma sposobu, aby być pewnym w momencie wykonywania żądania.

Moduł: SimpleAPI

/**
 * Simple POST and GET
 * @author Loreto Parisi (loretoparisi at gmail dot com)
*/
(function() {

  var SimpleAPI;

  SimpleAPI = (function() {

    var qs = require('querystring');

    /**
     * API Object model
     * @author Loreto Parisi (loretoparisi at gmail dot com)
     */
    function SimpleAPI(host,port,timeout,ssl,debug,json) {

      this.host=host;
      this.port=port;
      this.timeout=timeout;
      /** true to use ssl - defaults to true */
      this.ssl=ssl || true;
      /** true to console log */
      this.debug=debug;
      /** true to parse response as json - defaults to true */
      this.json= (typeof(json)!='undefined')?json:true;
      this.requestUrl='';
      if(ssl) { // use ssl
          this.http = require('https');
      } else { // go unsafe, debug only please
          this.http = require('http');
      }
    }

    /**
     * HTTP GET
     * @author Loreto Parisi (loretoparisi at gmail dot com)
     */
    SimpleAPI.prototype.Get = function(path, headers, params, success, error, timeout) {

      var self=this;
      if(params) {
        var queryString=qs.stringify(params);
        if( queryString ) {
          path+="?"+queryString;
        }
      }
      var options = {
        headers : headers,
        hostname: this.host,
        path: path,
        method: 'GET'
      };
      if(this.port && this.port!='80') { // port only if ! 80
        options['port']=this.port;
      }
      if(self.debug) {
        console.log( "SimpleAPI.Get", headers, params, options );
      }
      var request=this.http.get(options, function(response) {

          if(self.debug) { // debug
            console.log( JSON.stringify(response.headers) );
          }

          // Continuously update stream with data
          var body = '';
          response.on('data', function(d) {
              body += d;
          });
          response.on('end', function() {
            try {
              if(self.json) {
                var jsonResponse=JSON.parse(body);
                if(success) return success( jsonResponse );
              }
              else {
                if(success) return success( body );
              }
            } catch(ex) { // bad json
              if(error) return error( ex.toString() );
            }
          });
        });
        request.on('socket', function (socket) {
            socket.setTimeout( self.timeout );
            socket.on('timeout', function() {
                request.abort();
                if(timeout) return timeout( new Error('request timed out') );
            });
        });
        request.on('error', function (e) {
          // General error, i.e.
          //  - ECONNRESET - server closed the socket unexpectedly
          //  - ECONNREFUSED - server did not listen
          //  - HPE_INVALID_VERSION
          //  - HPE_INVALID_STATUS
          //  - ... (other HPE_* codes) - server returned garbage
          console.log(e);
          if(error) return error(e);
        });
        request.on('timeout', function () {
          // Timeout happend. Server received request, but not handled it
          // (i.e. doesn't send any response or it took to long).
          // You don't know what happend.
          // It will emit 'error' message as well (with ECONNRESET code).
          req.abort();
          if(timeout) return timeout( new Error('request timed out') );
        });

        self.requestUrl = (this.ssl?'https':'http') + '://' + request._headers['host'] + request.path;
        if(self.debug) {
          console.log("SimpleAPI.Post",self.requestUrl);
        }
        request.end();
    } //RequestGet

    /**
     * HTTP POST
     * @author Loreto Parisi (loretoparisi at gmail dot com)
     */
    SimpleAPI.prototype.Post = function(path, headers, params, body, success, error, timeout) {
      var self=this;

      if(params) {
        var queryString=qs.stringify(params);
        if( queryString ) {
          path+="?"+queryString;
        }
      }
      var bodyString=JSON.stringify(body)
      var _headers = {
        'Content-Length': Buffer.byteLength(bodyString)
      };
      for (var attrname in headers) { _headers[attrname] = headers[attrname]; }

      var options = {
        headers : _headers,
        hostname: this.host,
        path: path,
        method: 'POST',
        qs : qs.stringify(params)
      };
      if(this.port && this.port!='80') { // port only if ! 80
        options['port']=this.port;
      }
      if(self.debug) {
        console.log( "SimpleAPI.Post\n%s\n%s", JSON.stringify(_headers,null,2), JSON.stringify(options,null,2) );
      }
      if(self.debug) {
        console.log("SimpleAPI.Post body\n%s", JSON.stringify(body,null,2) );
      }
      var request=this.http.request(options, function(response) {

          if(self.debug) { // debug
            console.log( JSON.stringify(response.headers) );
          }

          // Continuously update stream with data
          var body = '';
          response.on('data', function(d) {
              body += d;
          });
          response.on('end', function() {
            try {
                console.log("END", body);
                var jsonResponse=JSON.parse(body);
                if(success) return success( jsonResponse );
            } catch(ex) { // bad json
              if(error) return error(ex.toString());
            }
          });

        });

        request.on('socket', function (socket) {
            socket.setTimeout( self.timeout );
            socket.on('timeout', function() {
                request.abort();
                if(timeout) return timeout( new Error('request timed out') );
            });
        });
        request.on('error', function (e) {
          // General error, i.e.
          //  - ECONNRESET - server closed the socket unexpectedly
          //  - ECONNREFUSED - server did not listen
          //  - HPE_INVALID_VERSION
          //  - HPE_INVALID_STATUS
          //  - ... (other HPE_* codes) - server returned garbage
          console.log(e);
          if(error) return error(e);
        });
        request.on('timeout', function () {
          // Timeout happend. Server received request, but not handled it
          // (i.e. doesn't send any response or it took to long).
          // You don't know what happend.
          // It will emit 'error' message as well (with ECONNRESET code).
          req.abort();
          if(timeout) return timeout( new Error('request timed out') );
        });

        self.requestUrl = (this.ssl?'https':'http') + '://' + request._headers['host'] + request.path;
        if(self.debug) {
          console.log("SimpleAPI.Post",self.requestUrl);
        }

        request.write( bodyString );
        request.end();

    } //RequestPost

    return SimpleAPI;

  })();

  module.exports = SimpleAPI

}).call(this);

Stosowanie:

// Parameters
// domain: example.com
// ssl:true, port:80
// timeout: 30 secs
// debug: true
// json response:true
var api = new SimpleAPI('posttestserver.com', 80, 1000 * 10, true, true, true); 

var headers = {
    'Content-Type' : 'application/json',
    'Accept' : 'application/json' 
};
var params = {
  "dir" : "post-test"
};
var method = 'post.php';

api.Post(method, headers, params, body
    , function(response) { // success
       console.log( response );
    }
    , function(error) { // error
      console.log( error.toString() );
    }
    , function(error) { // timeout
       console.log( new Error('timeout error') );
    });
loretoparisi
źródło
4

Po wielu problemach podczas tworzenia narzędzia niskiego poziomu do obsługi postu i otrzymywania próśb o mój projekt, postanowiłem opublikować tutaj mój wysiłek. Znacznie poniżej linii akceptowanej odpowiedzi znajduje się fragment kodu służący do wysyłania żądań POST HTTP i https o wysyłanie danych JSON.

const http = require("http")
const https = require("https")

// Request handler function
let postJSON = (options, postData, callback) => {

    // Serializing JSON
    post_data = JSON.stringify(postData)

    let port = options.port == 443 ? https : http

    // Callback function for the request
    let req = port.request(options, (res) => {
        let output = ''
        res.setEncoding('utf8')

        // Listener to receive data
        res.on('data', (chunk) => {
            output += chunk
        });

        // Listener for intializing callback after receiving complete response
        res.on('end', () => {
            let obj = JSON.parse(output)
            callback(res.statusCode, obj)
        });
    });

   // Handle any errors occurred while making request
    req.on('error', (err) => {
        //res.send('error: ' + err.message)
    });

    // Request is made here, with data as string or buffer
    req.write(post_data)
    // Ending the request
    req.end()
};

let callPost = () => {

    let data = {
        'name': 'Jon',
        'message': 'hello, world'
    }

    let options = {
        host: 'domain.name',       // Your domain name
        port: 443,                 // 443 for https and 80 for http
        path: '/path/to/resource', // Path for the request
        method: 'POST',            
        headers: {
            'Content-Type': 'application/json',
            'Content-Length': Buffer.byteLength(data)
        }
    }

    postJSON(options, data, (statusCode, result) => {
        // Handle response
        // Process the received data
    });

}
manyu
źródło
2
Nigdy nie używasz serializowanych danych post_data? czy zapisywanie jako obiekt js jest domyślnie konwertowane na bufor?
ThatBrianDude
3
let request = require('request');
let jsonObj = {};
request({
    url: "https://myapii.com/sendJsonData",
    method: "POST",
    json: true,
    body: jsonObj
    }, function (error, resp, body){
       console.log(resp);
});

Lub możesz użyć tej biblioteki:

let axios = require("axios");
let jsonObj = {};

const myJsonAPI = axios.create({
   baseURL: 'https://myapii.com',
   timeout: 120*1000
});

let response = await myJsonAPI.post("sendJsonData",jsonobj).catch(e=>{
    res.json(e);
});
console.log(response);
Jitendra virani
źródło
requestbiblioteka jest przestarzała.
Jurij Tkachenko
3

Axios to oparty na obietnicach klient HTTP dla przeglądarki i Node.js. Axios ułatwia wysyłanie asynchronicznych żądań HTTP do punktów końcowych REST i wykonywanie operacji CRUD. Można go używać w zwykłym JavaScript lub w bibliotece takiej jak Vue lub React.

const axios = require('axios');

        var dataToPost = {
          email: "your email",
          password: "your password"
        };

        let axiosConfiguration = {
          headers: {
              'Content-Type': 'application/json;charset=UTF-8',
              "Access-Control-Allow-Origin": "*",
          }
        };

        axios.post('endpoint or url', dataToPost, axiosConfiguration)
        .then((res) => {
          console.log("Response: ", res);
        })
        .catch((err) => {
          console.log("error: ", err);
        })
abhinavxeon
źródło
2

Publikowanie kolejnego przykładu axios żądania axios.post, który wykorzystuje dodatkowe opcje konfiguracji i niestandardowe nagłówki.

var postData = {
  email: "[email protected]",
  password: "password"
};

let axiosConfig = {
  headers: {
      'Content-Type': 'application/json;charset=UTF-8',
      "Access-Control-Allow-Origin": "*",
  }
};

axios.post('http://<host>:<port>/<path>', postData, axiosConfig)
.then((res) => {
  console.log("RESPONSE RECEIVED: ", res);
})
.catch((err) => {
  console.log("AXIOS ERROR: ", err);
})

Matthew Rideout
źródło
0

Za pomocą zależności żądania .

Proste rozwiązanie:

 import request from 'request'
 var data = {
        "host":"127.1.1.1",
        "port":9008
    }

request.post( baseUrl + '/peers/connect',
        {
            json: data,  // your payload data placed here
            headers: {
                'X-Api-Key': 'dajzmj6gfuzmbfnhamsbuxivc', // if authentication needed
                'Content-Type': 'application/json' 
            }
        }, function (error, response, body) {
            if (error) {
                callback(error, null)
            } else {
                callback(error, response.body)
            }
        });
Shashwat Gupta
źródło
3
skąd requestpochodzi?
CodyBugstein
Ta biblioteka jest przestarzała.
Jurij Tkachenko
0

Request-PromiseZapewnia odpowiedź opartą na obietnicach. Kody odpowiedzi HTTP inne niż 2xx spowodują odrzucenie obietnicy. Można to zastąpić, ustawiając opcje.simple = false

var options = {
  method: 'POST',
  uri: 'http://api.posttestserver.com/post',
  body: {
  some: 'payload'
 },
  json: true // Automatically stringifies the body to JSON
};

rp(options)
.then(function (parsedBody) {
    // POST succeeded...
})
.catch(function (err) {
    // POST failed...
});
veeresh yh
źródło