亚洲精品亚洲人成在线观看麻豆,在线欧美视频一区,亚洲国产精品一区二区动图,色综合久久丁香婷婷

              當(dāng)前位置:首頁 > IT技術(shù) > Web編程 > 正文

              nodejs入門(0)
              2022-04-29 13:55:45

              簡介

              一些回顧

              在開始之前,我們先簡單回顧一下目前為止已經(jīng)接觸過的web服務(wù)端:

              PHP:安裝后自動(dòng)運(yùn)行,搭配apache2食用,/etc/init.d/apache2 (restart)(start)(stop)調(diào)整apache2狀態(tài);php腳本放在/var/www/html中;直接localhost(或云服務(wù)器公網(wǎng)IP)+http默認(rèn)端口 訪問。

              python_socket服務(wù)端:直接python運(yùn)行寫好的腳本就行了;運(yùn)輸層內(nèi)容,運(yùn)行在某個(gè)套接字上;如果連接公網(wǎng)的話,IP需要填0.0.0.0。默認(rèn)不支持http協(xié)議,與其交互需要使用nc或python_socket客戶端。實(shí)現(xiàn)功能的方面和PHP差異很大。

              python模板(以flask為例):直接python運(yùn)行寫好的腳本就行了;運(yùn)行在某個(gè)套接字上,支持http協(xié)議,實(shí)現(xiàn)功能的能力和PHP不相上下。

              nodejs簡介

              簡單的說, Node.js 就是運(yùn)行在服務(wù)端的 JavaScript。

              從部署操作上來講,nodejs和PHP不同,而和python模板相似。安裝好nodejsnpm后,在nodejs服務(wù)端項(xiàng)目目錄下直接運(yùn)行相關(guān)程序就可開啟服務(wù):

              //server.js
              var http = require('http');
              
              http.createServer(function (request, response) {
              
                  // 發(fā)送 HTTP 頭部 
                  // HTTP 狀態(tài)值: 200 : OK
                  // 內(nèi)容類型: text/plain
                  response.writeHead(200, {'Content-Type': 'text/plain'});
                  
                  // 發(fā)送響應(yīng)數(shù)據(jù) "Hello World"
                  response.end('Hello World
              ');
              
              }).listen(8888);
              
              // 終端打印如下信息
              console.log('Server running at http://127.0.0.1:8888/');
              

              從理論上來講,nodejs和PHP就更不同了:

              #引自菜鳥教程#
              如果我們使用 PHP 來編寫后端的代碼時(shí),需要 Apache 或者 Nginx 的 HTTP 服務(wù)器,并配上 mod_php5 模塊和 php-cgi。
              
              從這個(gè)角度看,整個(gè)"接收 HTTP 請(qǐng)求并提供 Web 頁面"的需求就不需要 PHP 來處理。
              
              不過對(duì) Node.js 來說,概念完全不一樣了。使用 Node.js 時(shí),我們不僅僅 在實(shí)現(xiàn)一個(gè)應(yīng)用,同時(shí)還實(shí)現(xiàn)了整個(gè) HTTP 服務(wù)器。事實(shí)上,我們的 Web 應(yīng)用以及對(duì)應(yīng)的 Web 服務(wù)器基本上是一樣的。
              

              nodejs簡單使用

              讓我們先了解下 Node.js 應(yīng)用是由哪幾部分組成的:

              1. 引入 required 模塊:我們可以使用 require 指令來載入 Node.js 模塊。
              2. 創(chuàng)建服務(wù)器:服務(wù)器可以監(jiān)聽客戶端的請(qǐng)求,類似于 Apache 、Nginx 等 HTTP 服務(wù)器。
              3. 接收請(qǐng)求與響應(yīng)請(qǐng)求 服務(wù)器很容易創(chuàng)建,客戶端可以使用瀏覽器或終端發(fā)送 HTTP 請(qǐng)求,服務(wù)器接收請(qǐng)求后返回響應(yīng)數(shù)據(jù)。

              Express框架

              熟悉了nodejs的基本使用方式,我們就直接開始看框架。

              安裝與鏈接

              有兩種安裝方式:本地安裝;預(yù)先全局安裝后鏈接到本地。(均需root)

              本地安裝

              直接在nodejs項(xiàng)目下npm install express即可。

              全局鏈接

              先全局安裝:npm install express -g

              再進(jìn)入項(xiàng)目,進(jìn)行鏈接:npm link express

              基礎(chǔ)知識(shí)

              基本部署/做題識(shí)別

              var express = require('express');
              var app = express();
              

              創(chuàng)建服務(wù)器

              var server = app.listen(8081, function () {   
                  var host = server.address().address  
              	var port = server.address().port   
                  console.log(" http://%s:%s", host, port)  
              })
              

              路由、請(qǐng)求和相應(yīng)

              app.get('/', function (req, res) {
                 // --
              })
              

              感覺很類似python里的裝飾器@app.route。

              app.get()就是路由,決定了誰去響應(yīng)。這里的get指的是響應(yīng)get請(qǐng)求。app.post()也很易于理解。

              還有一個(gè)app.use(),感覺用途就比較廣了,這里先附一個(gè)用例,以后碰到躲不過的再詳細(xì)學(xué)。

              路由規(guī)則是app.use(path,router)定義的,router代表一個(gè)由express.Router()創(chuàng)建的對(duì)象,在路由對(duì)象中可定義多個(gè)路由規(guī)則。可是如果我們的路由只有一條規(guī)則時(shí),可直接接一個(gè)回調(diào)作為簡寫,也可直接使用app.getapp.post方法。即當(dāng)一個(gè)路徑有多個(gè)匹配規(guī)則時(shí),使用app.use()

              代碼可以提供public目錄下的圖片、css文件和js文件:
              app.use(express.static('public'));

              req是Request對(duì)象,表示 HTTP 請(qǐng)求,包含了請(qǐng)求查詢字符串,參數(shù),內(nèi)容,HTTP 頭部等屬性。

              res是Response對(duì)象,表示 HTTP 響應(yīng),即在接收到請(qǐng)求時(shí)向客戶端發(fā)送的 HTTP 響應(yīng)數(shù)據(jù)。

              app與express.route()

              上述的app(用express()生成的對(duì)象)可以看做一個(gè)Express應(yīng)用程序,它的作用是做全局的處理。而在稍微復(fù)雜一些的服務(wù)端邏輯中,我們還會(huì)看到express.route(),它被稱為迷你應(yīng)用程序,用于將邏輯移動(dòng)到單獨(dú)的文件中/"局部處理"。

              具體的,可以在nodejs工程的根目錄下創(chuàng)建app.js寫app相關(guān)的東西用于統(tǒng)籌,并創(chuàng)建routes文件夾用express.route寫細(xì)分邏輯。

              我們很快就可以在例題中見到類似的邏輯。

              例題1

              題目

              一個(gè)計(jì)算器。

              const express = require("express");
              const path = require("path");
              const vm2 = require("vm2");
              
              const app = express();
              app.use(express.urlencoded({ extended: true }));
              app.use(express.json());
              
              app.use(express.static("static"));
              
              const vm = new vm2.NodeVM();
              
              app.use("/eval", (req, res) => {
                const e = req.body.e;
                if (!e) {
                  res.send("wrong?");
                  return;
                }
                try {
                  res.send(vm.run("module.exports="+e)?.toString() ?? "no");
                } catch (e) {
                  console.log(e)
                  res.send("wrong?");
                }
              });
              
              app.use("/flag", (req, res) => {
                if(Object.keys(Object.prototype).length > 0) {
                  Object.keys(Object.prototype).forEach(k => delete Object.prototype[k]);
                  res.send(process.env.FLAG);
                } else {
                  res.send(Object.keys(Object.prototype));
                }
              })
              
              app.use("/source", (req, res) => {
                let p = req.query.path || "/src/index.js";
                p = path.join(path.resolve("."), path.resolve(p));
                console.log(p);
                res.sendFile(p);
              });
              
              app.use((err, req, res, next) => {
                console.log(err)
                res.redirect("index.html");
              });
              
              app.listen(process.env.PORT || 8888);
              

              考察一個(gè)很新的洞CVE-2022-21824.

              Due to the formatting logic of the "console.table()" function it was not safe to allow user controlled input to be passed to the "properties" parameter while simultaneously passing a plain object with at least one property as the first parameter, which could be "__proto__". The prototype pollution has very limited control, in that it only allows an empty string to be assigned to numerical keys of the object prototype.Node.js >= 12.22.9, >= 14.18.3, >= 16.13.2, and >= 17.3.1 use a null protoype for the object these properties are being assigned to.
              

              payload:console.table([{x:1}], ["__proto__"]);

              注意,這個(gè)payload要放到它的計(jì)算器里去,在本地的console里是沒用的!

              本地的console是客戶端瀏覽器自帶的JS,服務(wù)端的后端才是nodejs;新手(當(dāng)時(shí)的我)真的會(huì)犯這種低級(jí)失誤的。

              復(fù)現(xiàn)

              如果我沒理解錯(cuò)的話,那個(gè)洞的描述應(yīng)該說得是它在>= 12.22.9, >= 14.18.3, >= 16.13.2, and >= 17.3.1這幾個(gè)版本修掉了。我不會(huì)下12、14、16中舊的版本,8大版本下連table都沒有、10.22版本下直接報(bào)語法錯(cuò),所以就復(fù)現(xiàn)失敗了。

              挖個(gè)版本小坑:https://github.com/nodesource/distributions/issues/33#issuecomment-169345680

              復(fù)現(xiàn)效果:

              搬運(yùn)網(wǎng)圖:

              補(bǔ)充一些命令

              apt-cache madison <<package name>>查詢可以拿apt-get直接安裝的該軟件版本。

              apt-get install <<package name>>=<<version>>安裝指定版本;版本號(hào)從上面的回顯里復(fù)制完整的。

              從官方源安裝對(duì)應(yīng)大版本:

              curl -sL https://deb.nodesource.com/setup_【大版本號(hào)】.x | sudo -E bash -
              sudo apt-get install -y nodejs

              本文摘自 :https://www.cnblogs.com/

              開通會(huì)員,享受整站包年服務(wù)立即開通 >