Ngày nay, các ứng dụng web của chúng tôi có xu hướng tích hợp nhiều với các dịch vụ khác, cho dù đó là tương tác với dịch vụ REST như Twitter hay tải xuống hình ảnh từ Flickr. Sử dụng Node / JavaScript là một trong những ngôn ngữ phổ biến nhất để xử lý các ứng dụng như thế này. Dù bằng cách nào, bạn sẽ thực hiện rất nhiều yêu cầu HTTP, có nghĩa là bạn sẽ cần một mô-đun vững chắc để giúp việc viết mã trở nên dễ chịu hơn nhiều.
Các yêu cầu mô-đun cho đến nay là gói Node (không chuẩn) phổ biến nhất để thực hiện các yêu cầu HTTP. Trên thực tế, nó thực sự chỉ là một trình bao bọc xung quanh Node được tích hợp sẵn http vì vậy bạn có thể tự mình đạt được tất cả các chức năng tương tự với httpnhưng request chỉ làm cho nó dễ dàng hơn rất nhiều.
Contents
Thực hiện các yêu cầu HTTP
Mặc dù có khá nhiều tùy chọn có sẵn cho bạn trong request (nhiều trong số đó chúng tôi sẽ đề cập trong suốt bài viết này), nó cũng có thể khá đơn giản để sử dụng. Ví dụ “hello world” cho thư viện này dễ dàng như chuyển một URL và một lệnh gọi lại:
const request = require('request'); request('https://ezerror.com', function(err, res, body) { console.log(body); });
Đoạn mã trên gửi một yêu cầu HTTP GET đến ezerror.com và sau đó in HTML trả về ra màn hình. Loại yêu cầu này hoạt động đối với bất kỳ điểm cuối HTTP nào, cho dù nó trả về HTML, JSON, hình ảnh hay bất kỳ thứ gì khác.
Đối số đầu tiên để request có thể là một chuỗi URL hoặc một đối tượng tùy chọn. Dưới đây là một số tùy chọn phổ biến hơn mà bạn sẽ gặp trong các ứng dụng của mình:
- url: URL đích của yêu cầu HTTP
- method: Phương thức HTTP sẽ được sử dụng (GET, POST, DELETE, v.v.)
- headers: Một đối tượng của tiêu đề HTTP (khóa-giá trị) sẽ được đặt trong yêu cầu
- form: Một đối tượng chứa dữ liệu dạng khóa-giá trị
const request = require('request'); const options = { url: 'https://www.reddit.com/r/funny.json', method: 'GET', headers: { 'Accept': 'application/json', 'Accept-Charset': 'utf-8', 'User-Agent': 'my-reddit-client' } }; request(options, function(err, res, body) { let json = JSON.parse(body); console.log(json); });
Sử dụng optionsyêu cầu này sử dụng phương thức GET để truy xuất dữ liệu JSON trực tiếp từ Reddit, được trả về dưới dạng một chuỗi trong body. Từ đây, bạn có thể sử dụng JSON.parse và sử dụng dữ liệu như một đối tượng JavaScript bình thường.
Định dạng yêu cầu tương tự này có thể được sử dụng cho bất kỳ loại phương thức HTTP, cho dù đó là XÓA, NHẤP, ĐĂNG hay TÙY CHỌN. Mặc dù, không phải tất cả các phương pháp đều được sử dụng hoàn toàn giống nhau. Một số, như phương thức POST, có thể bao gồm dữ liệu trong yêu cầu. Có một số cách có thể gửi dữ liệu này, một số trong số đó là:
- body: MỘT Buffer, Stringhoặc Stream (có thể là một đối tượng nếu json được đặt thành true)
- form: Một đối tượng của dữ liệu cặp khóa-giá trị (chúng ta sẽ xem xét vấn đề này sau)
- multipart: Một mảng các đối tượng có thể chứa các thuộc tính tiêu đề và nội dung của riêng chúng
Mỗi cách đáp ứng một nhu cầu khác nhau (và thậm chí còn có nhiều cách để gửi dữ liệu, bạn có thể tìm thấy trong phần này của README của yêu cầu). Các request Tuy nhiên, có chứa một số phương pháp tiện lợi làm cho những phương pháp này dễ làm việc hơn một chút, vì vậy hãy nhớ đọc toàn bộ tài liệu để tránh làm cho mã của bạn khó khăn hơn bình thường.
Nói về các phương thức trợ giúp, một cách ngắn gọn hơn nhiều để gọi các phương thức HTTP khác nhau là sử dụng các phương thức trợ giúp tương ứng được cung cấp. Dưới đây là một vài trong số những cái thường được sử dụng hơn:
- request.get(options, callback)
- request.post(options, callback)
- request.head(options, callback)
- request.delete(options, callback)
Mặc dù điều này sẽ không giúp bạn tiết kiệm rất nhiều dòng mã, nhưng ít nhất nó sẽ làm cho mã của bạn dễ hiểu hơn một chút bằng cách cho phép bạn chỉ nhìn vào phương thức đang được gọi và không phải phân tích cú pháp qua tất cả các tùy chọn khác nhau để tìm. nó.
Các hình thức
Cho dù bạn đang giao tiếp với REST API hay tạo một bot để thu thập dữ liệu và gửi dữ liệu trên các trang web, tại một số điểm, bạn sẽ cần gửi dữ liệu cho một biểu mẫu. Như mọi khi với requestđiều này có thể được thực hiện theo một số cách khác nhau, tùy thuộc vào nhu cầu của bạn.
Đối với các biểu mẫu thông thường (được mã hóa URL, với MIME loại application/x-www-form-urlencoded), tốt nhất bạn nên sử dụng .post() phương thức tiện lợi với đối tượng biểu mẫu:
let options = { url: 'http://http://mockbin.com/request', form: { email: '[email protected]', password: 'myPassword' } }; request.post(options, callback);
Thao tác này sẽ tải lên dữ liệu giống như biểu mẫu HTML, với hạn chế duy nhất là bạn không thể tải tệp lên theo cách này. Để làm được điều đó, bạn cần sử dụng formData thay vào đó, sử dụng dữ liệu biểu mẫu thư viện bên dưới.
Sử dụng formDatabây giờ chúng tôi có thể chuyển dữ liệu tệp đến máy chủ thông qua BufferS, Streams, hoặc thậm chí dữ liệu không phải tệp (như trước đây) với các cặp khóa-giá trị đơn giản.
let formData = { // Pass single file with a key profile_pic: fs.createReadStream(__dirname + '/me.jpg'), // Pass multiple files in an array attachments: [ fs.readFileSync(__dirname + '/cover-letter.docx'), // Buffer fs.createReadStream(__dirname + '/resume.docx'), // Stream ], // Pass extra meta-data with your files detailed_file: { value: fs.createReadStream(__dirname + '/my-special-file.txt'), options: { filename: 'data.json', contentType: 'application/json' } }, // Simple key-value pairs username: 'ScottWRobinson' }; request.post('http://http://mockbin.com/request', {formData: formData}, callback);
Thao tác này sẽ gửi tệp của bạn với kiểu MIME là multipart/form-datalà một tải lên biểu mẫu nhiều phần.
Mặc dù điều này là quá đủ cho hầu hết các trường hợp sử dụng của người dùng, nhưng đôi khi bạn cần kiểm soát chi tiết hơn nữa, chẳng hạn như CLRF trước / sau (dòng mới), phân khúc hoặc chỉ định hệ số của riêng bạn. Để biết thêm thông tin về các tùy chọn bổ sung này, hãy xem phần này của request ĐỌC SÁCH.
Dòng
Theo tôi, một trong những tính năng được sử dụng ít nhất trong nhiều ngôn ngữ lập trình là luồng. Tính hữu dụng của chúng không chỉ là các yêu cầu mạng, nhưng đây là một ví dụ hoàn hảo về lý do tại sao bạn nên sử dụng chúng. Để có mô tả ngắn gọn về cách thức và lý do bạn nên sử dụng chúng, hãy xem phần “Luồng” của bài viết Máy chủ HTTP Node cho Cung cấp tệp tĩnh.
Tóm lại, việc sử dụng luồng cho lượng lớn dữ liệu (như tệp) có thể giúp giảm thời gian phản hồi và bộ nhớ của ứng dụng. Để làm cho điều này dễ sử dụng hơn, mỗi request phương pháp có thể pipe đầu ra của họ cho một luồng khác.
Trong ví dụ này, chúng tôi tải xuống biểu trưng Node.js bằng cách sử dụng yêu cầu GET và truyền nó vào một tệp cục bộ:
let fileStream = fs.createWriteStream('node.png'); request('https://nodejs.org/static/images/logos/nodejs-new-white-pantone.png').pipe(fileStream);
Ngay sau khi yêu cầu HTTP bắt đầu trả về các phần của hình ảnh đã tải xuống, nó sẽ ‘chuyển’ dữ liệu đó trực tiếp đến tệp ‘node.png’.
Tải xuống tệp theo cách này cũng có một số lợi ích khác. Luồng rất tốt để áp dụng các phép biến đổi trên dữ liệu khi nó được tải xuống. Vì vậy, ví dụ: giả sử bạn đang tải xuống một lượng lớn dữ liệu nhạy cảm với request cần được mã hóa ngay lập tức. Để làm điều này, bạn có thể áp dụng một biến đổi mã hóa bằng cách chuyển đầu ra của request đến crypto.createCipher:
let url="http://example.com/super-sensitive-data.json"; let pwd = new Buffer('myPassword'); let aesTransform = crypto.createCipher('aes-256-cbc', pwd); let fileStream = fs.createWriteStream('encrypted.json'); request(url) .pipe(aesTransform) // Encrypts with aes256 .pipe(fileStream) // Write encrypted data to a file .on('finish', function() { console.log('Done downloading, encrypting, and saving!'); });
Thật dễ dàng để bỏ qua các luồng và nhiều người làm như vậy khi họ đang viết mã, nhưng chúng có thể giúp ích cho hiệu suất của bạn một chút, đặc biệt là với một thư viện như request.
Khác. Cấu hình
Có nhiều thứ hơn đối với các yêu cầu HTTP ngoài việc chỉ định một URL và tải xuống dữ liệu. Đối với các ứng dụng lớn hơn và đặc biệt là những ứng dụng phải hỗ trợ nhiều môi trường hơn, yêu cầu của bạn có thể cần xử lý khá nhiều tham số cấu hình, như proxy hoặc chứng chỉ tin cậy SSL đặc biệt.
Một điều quan trọng. đặc điểm cần chỉ ra là request.defaults() cho phép bạn chỉ định các tham số mặc định để bạn không phải cung cấp chúng cho mọi yêu cầu bạn đưa ra.
let req = request.defaults({ headers: { 'x-access-token': '123abc', 'User-Agent': 'my-reddit-client' } }); req('http://your-api.com', function(err, res, body) { console.log(body); });
Bây giờ, trong ví dụ trên, tất cả các yêu cầu được thực hiện với req sẽ luôn có tiêu đề x-access-token và User-Agent đặt. Điều này lý tưởng để đặt các tiêu đề như thế này, máy chủ proxy hoặc cấu hình TLS / SSL.
Trong suốt phần còn lại của phần này, chúng ta sẽ xem xét một số tính năng phổ biến hơn mà bạn sẽ gặp:
Proxy
Cho dù máy tính của bạn sử dụng proxy của công ty hay bạn muốn chuyển hướng lưu lượng truy cập của mình đến một quốc gia khác, tại một số thời điểm, bạn có thể cần chỉ định địa chỉ proxy. Cách đơn giản nhất để đạt được điều này là sử dụng proxylấy một địa chỉ mà trong đó lưu lượng truy cập được ủy quyền qua:
let options = { url: 'https://www.google.com', proxy: 'http://myproxy.com' }; request(options, callback);
Các options là một cách để chỉ định proxy, nhưng request cũng sử dụng các biến môi trường sau để định cấu hình kết nối proxy:
- HTTP_PROXY / http_proxy
- HTTPS_PROXY / https_proxy
- NO_PROXY / no_proxy
Điều này cho phép bạn kiểm soát nhiều hơn một chút, chẳng hạn như thiết lập các trang web không nên được hỗ trợ thông qua NO_PROXY.
TLS / SSL
Đôi khi một API cần có thêm một số bảo mật và do đó yêu cầu chứng chỉ ứng dụng khách. Điều này thực sự khá phổ biến với các API công ty tư nhân, vì vậy bạn nên biết cách thực hiện điều này.
Một trường hợp có thể xảy ra khác là bạn muốn các yêu cầu HTTP của mình tin cậy một cách rõ ràng cơ quan cấp chứng chỉcó thể bao gồm các chứng chỉ do bạn hoặc công ty của bạn tự ký.
Như với tất cả các cấu hình khác mà chúng tôi đã thấy cho đến nay, chúng được đặt trong options:
const fs = require('fs'); const request = require('request'); let myCertFile = fs.readFileSync(__dirname + '/ssl/client.crt') let myKeyFile = fs.readFileSync(__dirname + '/ssl/client.key') let myCaFile = fs.readFileSync(__dirname + '/ssl/ca.cert.pem') var options = { url: 'https://mockbin.com/request', cert: myCertFile, key: myKeyFile, passphrase: 'myPassword', ca: myCaFile }; request.get(options);
Xác thực cơ bản
Các trang web sử dụng xác thực truy cập cơ bản vẫn có thể được truy cập bằng cách sử dụng auth:
const request = require('request'); var options = { url: 'https://mockbin.com/request', auth: { username: 'ScottWRobinson', password: 'myPassword' } }; request.get(options);
Tùy chọn này đặt một trong các tiêu đề HTTP là “authorization”: “Basic c2NvdHQ6cGFzc3dvcmQh”. Chuỗi ‘Cơ bản’ trong tiêu đề ‘ủy quyền’ tuyên bố đây là yêu cầu Xác thực cơ bản và chuỗi chữ và số theo sau là mã hóa RFC2045-MIME (một biến thể của Base64) tên người dùng và mật khẩu của chúng tôi.
Chuyển hướng
Tôi nhận thấy rằng trong một số ứng dụng, chẳng hạn như duyệt web, có khá nhiều trường hợp bạn cần thực hiện theo các chuyển hướng để yêu cầu của bạn thành công. Như bạn có thể đoán, có một tùy chọn để chỉ định xem có theo các chuyển hướng theo mặc định hay không, nhưng request thậm chí còn đi xa hơn một bước và sẽ cho phép bạn cung cấp một hàm có thể được sử dụng để xác định có điều kiện xem chuyển hướng có nên được tuân theo hay không.
Một số tùy chọn chuyển hướng là:
- followRedirect: Nếu true, sau đó làm theo tất cả các chuyển hướng HTTP 3xx. Hoặc gửi một function(res) {} được sử dụng để xác định xem có đi theo chuyển hướng hay không
- followAllRedirects: Thực hiện theo tất cả các chuyển hướng HTTP 3xx không GET
- maxRedirects: Số lần tối đa để theo dõi chuyển hướng theo chuỗi (mặc định là 10)
Sự kết luận
Không nghi ngờ gì nữa request là một mô-đun mạnh mẽ và có thể là một mô-đun mà bạn sẽ sử dụng thường xuyên. Với tất cả các tính năng mà nó cung cấp, nó có thể hoạt động như một điểm khởi đầu tuyệt vời cho mọi thứ từ trình thu thập thông tin web đến thư viện khách hàng cho API của bạn.
Có một số tùy chọn và cấu hình khác có thể được sử dụng với request hơn những gì chúng tôi đã hiển thị ở đây, vì vậy hãy nhớ xem tài liệu để biết thêm chi tiết. Hãy nhớ rằng không phải tất cả mọi thứ trong mô-đun đều được ghi lại, vì vậy bạn có thể cần thực hiện thêm một số tìm kiếm / thử nghiệm để tìm ra câu trả lời của mình.
Bạn đã sử dụng request trong bất kỳ dự án nào của bạn? Nếu vậy, làm thế nào?