Làm thế nào là một yêu cầu POST HTTP được thực hiện trong node.js?


946

Làm cách nào tôi có thể thực hiện một yêu cầu POST HTTP gửi đi, với dữ liệu, trong node.js?


16
Như được đề xuất trong câu trả lời của Jed Watson , tôi thực sự khuyên bạn nên sử dụng yêu cầu trừ khi bạn viết API cấp thấp.
namuol

4
Bạn chỉ có thể sử dụng node-fetchtriển khai fetchphương thức JavaScript gốc để thực hiện các yêu cầu HTTP.
Fez Vrasta

Bài đăng này bao gồm các kịch bản sử dụng cơ bản để sử dụng yêu cầu. blog.modulus.io/node.js-tutorial-how-to-use-request-module
Shaswat Rungta

Câu trả lời:


855

Dưới đây là ví dụ về việc sử dụng node.js để tạo yêu cầu POST cho API Trình biên dịch của Google:

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

Tôi đã cập nhật mã để hiển thị cách đăng dữ liệu từ một tệp, thay vì chuỗi được mã hóa cứng. Nó sử dụng fs.readFilelệnh async để đạt được điều này, đăng mã thực tế sau khi đọc thành công. Nếu có lỗi, nó sẽ bị ném và nếu không có dữ liệu, quy trình sẽ thoát với giá trị âm để chỉ ra lỗi.


4
Là tiêu đề chiều dài nội dung được tính toán chính xác? Được cho là byte, phải không?
Eric

7
Lưu ý rằng querystring.stringify() không hỗ trợ các đối tượng lồng nhau , vì vậy bạn có thể muốn sử dụng qs.stringify()thay thế.
johndodo

51
Content-Lengthlà byte và không nhất thiết phải là độ dài chuỗi (UTF-16, v.v.). Sử dụng Buffer.byteLength(data)sẽ luôn luôn đúng.
greenimpala

4
để gửi postdata tiêu chuẩn, đối tượng trong querystring.stringifyphải là đối tượng dữ liệu của riêng bạn, không phải là rác được hiển thị trong câu trả lời này (có thể hữu ích cho các đối tượng dựa trên tệp?). Tôi đã bị mắc kẹt trong đó từ lâu ... stackoverflow.com/questions/9768192/ cấp đã cung cấp giải pháp hoàn chỉnh của tôi
RozzA

7
Gotcha: Nếu bạn đang sử dụng trang web được mã hóa ssl, bạn sẽ cần thư viện "https". Bạn không thể thay đổi cổng thành 443.
Dave Collins

1137

Điều này sẽ dễ dàng hơn rất nhiều nếu bạn sử dụng thư viện yêu cầu .

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

Ngoài việc cung cấp một cú pháp đẹp, nó làm cho các yêu cầu json trở nên dễ dàng, xử lý ký oauth (đối với twitter, v.v.), có thể thực hiện các hình thức đa phần (ví dụ để tải lên tệp) và phát trực tuyến.

Để cài đặt yêu cầu sử dụng lệnh npm install request


153
{form: {key: 'value'}} nên được thay thế bằng {json: {key: 'value'}} (vì câu hỏi không dành riêng cho biểu mẫu). Người ta cũng phải hiểu 'hình thức' và 'json' là các từ khóa thư viện yêu cầu và không phải là một phần của dữ liệu tùy chỉnh (tầm thường như nhận xét cuối cùng này có thể xuất hiện, tôi phải mất một thời gian để tìm ra nó ...)
blacelle

7
Tôi tiếp tục quay lại câu hỏi và trả lời này. Nó thực sự nên là "câu trả lời" cho câu hỏi.
Spencer Kormos

6
Bạn xứng đáng với một huy hiệu vàng hoàn toàn cho câu trả lời này. Nó hữu ích hơn nhiều so với cái được chấp nhận ... và nó đã tồn tại từ năm 2012? Wow
Zoltán Schmidt

3
bạn có thể cần thêm sự phụ thuộc bằng cách chạy lệnh này 'npm install --save request'
Shady Sherif

18
Thư viện này đã bị phản đối
Evorlor

138

Bạn có thể sử dụng thư viện yêu cầu. https://www.npmjs.com/package/request

var request = require('request');

Để đăng dữ liệu JSON:

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

Để đăng dữ liệu 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);
});

Sau khi xem xét trong tài liệu của họ. nó tuyên bố như sau: json - thiết lập phần thân nhưng biểu thị giá trị JSON và thêm tiêu đề Content-type: application / json. Ngoài ra, phân tích nội dung phản hồi dưới dạng JSON. Điều đó có nghĩa là khi json = true, nó sẽ đặt tiêu đề và json và body. Mặt khác, không có tiêu đề nào được đặt và phân tích thành văn bản. (Giống như ví dụ XML ở trên). Điều đó làm cho API yêu cầu tiện dụng và đơn giản nhưng khá khó hiểu vào lần đầu tiên.
Josiah Choi

Đó là về mặt kỹ thuật trong tài liệu của họ, nhưng không có ví dụ nào cho thấy điều đó - chỉ có dữ liệu biểu mẫu. Đó là một cây kim trong đống cỏ khô, và như vậy, nó là một sự thay đổi lớn, vì đây là cách thường xuyên thứ hai tôi sử dụng ajax trong JS, và chắc chắn là một trong những phổ biến nhất trên web.
Kyle Baker

Sử dụng request.post là IMO đẹp hơn một chút so với chỉ định POST làm phương thức. Dưới đây là một số ví dụ từ GitHub để sử dụng request.post
drorw

12
Thư viện này đã bị phản đối
Evorlor

44

Tôi sử dụng Restlerkim cho mục đích sản xuất. Cả hai đều mạnh hơn nhiều so với httprequest bản địa. Có thể yêu cầu xác thực cơ bản, nhập tiêu đề đặc biệt hoặc thậm chí tải lên / tải xuống tệp.

Đối với hoạt động post / get, chúng cũng sử dụng đơn giản hơn nhiều so với các cuộc gọi ajax thô sử dụng httprequest.

needle.post('https://my.app.com/endpoint', {foo:'bar'}, 
    function(err, resp, body){
        console.log(body);
});

Tôi đã thử yêu cầu, nút-form-data và superagent trước kim. kim là người duy nhất hoạt động chính xác với tôi khi cố gắng thực hiện tải lên tệp biểu mẫu nhiều phần.
Paul Young

35

Đơn giản và không phụ thuộc. Sử dụng một lời hứa để bạn có thể chờ đợi kết quả. Nó trả về phần thân phản hồi và không kiểm tra mã trạng thái phản hồi.

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

Sử dụng:

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',
    })
})

Là những gì writephương pháp trên req,write()được sử dụng cho?
Ari

@Ari Điều đó viết phần thân của yêu cầu ... nodejs.org/api/ Từ
mpen

21

Bạn cũng có thể sử dụng Requestify , một ứng dụng HTTP đơn giản và thú vị mà tôi đã viết cho nodeJS + nó hỗ trợ bộ đệm.

Chỉ cần làm như sau:

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

1
Nó không hoạt động với tôi, xem vấn đề ở đây: github.com/ranm8/requestify/issues/2
Erel Segal-Halevi

20

Cập nhật 2020:

Tôi đã thực sự thích phin - Ứng dụng HTTP Node.js siêu nhẹ

Nó có thể được sử dụng theo hai cách khác nhau. Một với Lời hứa (Async / Await) và cái còn lại với kiểu gọi lại truyền thống.

Cài đặt qua: npm i phin

Trực tiếp từ đó là README với await:

const p = require('phin')

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


Kiểu không được yêu cầu (gọi lại):

const p = require('phin').unpromisified

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

Kể từ năm 2015 , hiện nay có rất nhiều thư viện khác nhau có thể thực hiện điều này với mã hóa tối thiểu. Tôi rất thích các thư viện trọng lượng nhẹ thanh lịch cho các yêu cầu HTTP trừ khi bạn thực sự cần kiểm soát các công cụ HTTP cấp thấp.

Một thư viện như vậy là Unirest

Để cài đặt nó, sử dụng npm.
$ npm install unirest

Và vào Hello, World!ví dụ mà mọi người đều quen thuộc.

var unirest = require('unirest');

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


Thêm:
Rất nhiều người cũng đề nghị sử dụng yêu cầu [2]

Cần lưu ý rằng đằng sau hậu trường Unirestsử dụng requestthư viện.

Unirest cung cấp các phương thức để truy cập trực tiếp vào đối tượng yêu cầu.

Thí dụ:

var Request = unirest.get('http://mockbin.com/request');

1
Một cái khác tôi thấy có vẻ khá tốt là github.com/request/request có vẻ phổ biến hơn một chút so với ít nhất là trong bài viết này
Lochlan

Tôi có thể chứng thực để yêu cầu. Đó là một thư viện rất tốt. Tôi thấy rằng yêu cầu đó cung cấp nhiều chức năng cấp thấp hơn nên phù hợp để sử dụng nó cho các ứng dụng cụ thể. Khi tôi không nhất thiết phải quan tâm đến những thứ cấp thấp, tôi thấy Unirest là đầy đủ.
Levi Roberts

Tại sao unirest sẽ được coi là nhẹ khi nó phụ thuộc vào yêu cầu? Yêu cầu có 22 phụ thuộc, tôi không thấy nó nhẹ như thế nào
raphadko 18/03/18

@raphadko Tôi chắc chắn rằng trong những năm qua, sự phình to đã xảy ra. Hãy chắc chắn kiểm tra dấu thời gian khi tôi đăng câu trả lời của mình;)
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);
});

Có cách nào để xem nội dung bài đăng yêu cầu hoặc theo yêu cầu hoặc phản hồi không?
jacoballenwood

17

Có hàng tá thư viện mã nguồn mở có sẵn mà bạn có thể sử dụng để thực hiện yêu cầu POST HTTP trong Nút.

1. Axios (Khuyến nghị)

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. Kim

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. Yêu cầu

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. Mô đun HTTPS bản địa

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

Để biết chi tiết, hãy xem bài viết này .


14

Đây là cách đơn giản nhất tôi sử dụng để thực hiện yêu cầu: sử dụng mô-đun 'request'.

Lệnh cài đặt mô-đun 'request':

$ npm install request

Mã ví dụ:

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)

});

Bạn cũng có thể sử dụng mô-đun 'http' tích hợp của Node.js để thực hiện yêu cầu.


1
Thư viện này đã bị phản đối
Yuri Tkachenko

12

Tôi thích sự đơn giản của superagent ( https://github.com/visionmedia/superagent ). API giống nhau trên cả nút và trình duyệt.

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

Ngoài ra còn có nút tìm nạp ( https://www.npmjs.com/package/node-fetch ), có API khớp với fetchcác trình duyệt - tuy nhiên điều này yêu cầu mã hóa chuỗi truy vấn thủ công, không tự động xử lý các loại nội dung hoặc Vì vậy, bất kỳ công việc khác superagent làm.


1
Và ngược lại với kim, unirest và co, nó mang lại sự nhẹ nhàng (superagent: 16k, unirest: 1M, kim: 530K)
Lars

9

Nếu bạn đang tìm kiếm các yêu cầu HTTP dựa trên lời hứa, các axios thực hiện công việc của nó một cách độc đáo.

  const axios = require('axios');

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

HOẶC LÀ

await axios.post('/user', {firstName: 'Fred',lastName: 'Flintstone'})

6

Để gửi phần còn lại / Yêu cầu JSON
Chúng ta chỉ cần sử dụng gói yêu cầu và lưu các giá trị chúng ta phải gửi trong biến Json.

Trước tiên hãy cài đặt gói yêu cầu trong bảng điều khiển của bạn bằng cách yêu cầu cài đặt npm - lưu

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

2
Không bao giờ xây dựng chuỗi truy vấn của riêng bạn. Bạn đang bỏ qua việc mã hóa chính xác các giá trị của bạn. Node.js có một thư viện cho mục đích này: nodejs.org/api/queryopes.html
Brad

Thư viện này đã bị phản đối
Yuri Tkachenko

4

Tôi đã tìm thấy một video giải thích về cách đạt được điều này: https://www.youtube.com/watch?v=nuw48-u3Yrg

Nó sử dụng mô-đun "http" mặc định cùng với các mô-đun "chuỗi truy vấn" và "chuỗi xây dựng". Ứng dụng lấy hai số (sử dụng hai hộp văn bản) từ một trang web và sau khi gửi, trả về tổng của hai số đó (cùng với việc duy trì các giá trị trong hộp văn bản). Đây là ví dụ tốt nhất tôi có thể tìm thấy ở bất cứ nơi nào khác.

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

4

Đây là giải pháp của tôi cho POSTGET.

Về Postphương pháp:

Nếu phần thân là một đối tượng JSON, thì điều quan trọng là phải giải tuần tự hóa nó JSON.stringifyvà có thể đặt Content-Lenghttiêu đề tương ứng:

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

trước khi viết nó cho yêu cầu:

request.write( bodyString );

Về cả hai GetPostphương pháp:

Điều này timeoutcó thể xảy ra như một sự socketngắt kết nối, vì vậy bạn phải đăng ký trình xử lý của nó như:

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

trong khi requestxử lý là

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

Tôi đề nghị để đăng ký cả hai xử lý.

Phần thân phản hồi bị chunk, vì vậy bạn phải ghép các phần trong phần dataxử lý:

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

Tại endcác bodysẽ chứa cơ thể đáp ứng toàn bộ:

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

Thật an toàn khi kết hợp với một try... bắt theJSON.parse` vì bạn không thể chắc chắn rằng đó là một json được định dạng tốt thực sự và không có cách nào để chắc chắn về điều đó tại thời điểm bạn thực hiện yêu cầu.

Mô-đun: 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);

Sử dụng:

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

4

Sau khi vật lộn rất nhiều trong khi tạo ra một tiện ích cấp thấp để xử lý bài đăng và nhận yêu cầu cho dự án của tôi, tôi quyết định đăng nỗ lực của mình ở đây. Phần lớn các dòng câu trả lời được chấp nhận, đây là đoạn trích để thực hiện các yêu cầu POST và https POST để gửi dữ liệu 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
    });

}

2
Bạn không bao giờ sử dụng post_data nối tiếp? mặc định viết như đối tượng js chuyển sang bộ đệm?
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);
});

Hoặc bạn có thể sử dụng thư viện này:

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

requestthư viện đã bị phản đối
Yuri Tkachenko

3

Axios là một ứng dụng HTTP dựa trên lời hứa cho trình duyệt và Node.js. Axios giúp dễ dàng gửi các yêu cầu HTTP không đồng bộ đến các điểm cuối REST và thực hiện các hoạt động CRUD. Nó có thể được sử dụng trong JavaScript đơn giản hoặc với một thư viện như Vue hoặc 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);
        })

2

Đăng một ví dụ về axios khác của yêu cầu axios.post sử dụng các tùy chọn cấu hình bổ sung và các tiêu đề tùy chỉnh.

var postData = {
  email: "test@test.com",
  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);
})


0

Bằng cách sử dụng phụ thuộc yêu cầu .

Giải pháp đơn giản:

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

3
không requestđến từ đâu
CodyBugstein

Thư viện này đã bị phản đối
Yuri Tkachenko

0

Request-PromiseCung cấp phản ứng dựa trên lời hứa. mã phản hồi http khác 2xx sẽ khiến lời hứa bị từ chối. Điều này có thể được ghi đè bằng cách đặt tùy chọn.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...
});
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.