成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

node學(xué)習(xí)之路(一)—— 網(wǎng)絡(luò)請(qǐng)求

bovenson / 1077人閱讀

摘要:域套接字使用或指定請(qǐng)求方法的字符串。請(qǐng)求路徑包含非法字符時(shí)拋出異常。保持資源池周圍的套接字在未來被用于其它請(qǐng)求。默認(rèn)值為當(dāng)使用的時(shí)候,通過正在保持活動(dòng)的套接字發(fā)送包的頻繁程度。

文章來源:小青年原創(chuàng)
發(fā)布時(shí)間:2016-09-29
關(guān)鍵詞:JavaScript,nodejs,http,url ,Query String,爬蟲
轉(zhuǎn)載需標(biāo)注本文原始地址: http://zhaomenghuan.github.io...

前言

一直以來想學(xué)習(xí)一下node,一來是自己目前也沒有什么時(shí)間去學(xué)習(xí)服務(wù)器端語言,但是有時(shí)候又想自己擼一下服務(wù)器端,本著愛折騰的精神開始寫一寫關(guān)于node的文章記錄學(xué)習(xí)心得。本系列文章不會(huì)過多去講解node安裝、基本API等內(nèi)容,而是通過一些實(shí)例去總結(jié)常用用法。本文主要講解node網(wǎng)絡(luò)操作的相關(guān)內(nèi)容,node中的網(wǎng)絡(luò)操作依賴于http模塊,http模塊提供了兩種使用方式:

作為服務(wù)器端使用,創(chuàng)建一個(gè)http服務(wù)器,監(jiān)聽http客戶端請(qǐng)求并返回響應(yīng);

作為客戶端使用,發(fā)起一個(gè)http客戶端請(qǐng)求,獲取服務(wù)器端響應(yīng)。

node http模塊創(chuàng)建服務(wù)器 node 處理 get 請(qǐng)求實(shí)例

畢竟作為一個(gè)前端,我們經(jīng)常需要自己搭建一個(gè)服務(wù)器做測(cè)試,這里我們先來講一下node http模塊作為服務(wù)器端使用。首先我們需要,使用createServer創(chuàng)建一個(gè)服務(wù),然后通過listen監(jiān)聽客服端http請(qǐng)求。

我們可以創(chuàng)建一個(gè)最簡單的服務(wù)器,在頁面輸出hello world,我們可以創(chuàng)建helloworld.js,內(nèi)容如下:

var http = require("http");

http.createServer(function(request, response){
    response.writeHead(200, { "Content-Type": "text-plain" });
    response.end("hello world!")
}).listen(8888);

在命令行輸入node helloworld.js即可,我們打開在瀏覽器打開http://127.0.0.1:8888/就可以看到頁面輸出hello world!。

下面我們?cè)诒镜貙懸粋€(gè)頁面,通過jsonp訪問我們創(chuàng)建的node服務(wù)器:



    
        
        
    
    
        

我們當(dāng)然需要將上述node服務(wù)器中的代碼稍作修改:

var http = require("http"); // 提供web服務(wù)
var url = require("url");    // 解析GET請(qǐng)求
  
var data = {
    "name": "zhaomenghuan", 
    "age": "22"
};
  
http.createServer(function(req, res){  
    // 將url字符串轉(zhuǎn)換成Url對(duì)象
    var params = url.parse(req.url, true);  
    console.log(params);
    // 查詢參數(shù)
    if(params.query){
        // 根據(jù)附件條件查詢
        if(params.query.userid === "xiaoqingnian"){
            // 判斷是否為jsonp方式請(qǐng)求,若是則使用jsonp方式,否則為普通web方式
            if (params.query.callback) {  
                var resurlt =  params.query.callback + "(" + JSON.stringify(data) + ")";
                res.end(resurlt);  
            } else {  
                res.end(JSON.stringify(data));
            }
        } 
    }      
}).listen(8888);

我們?cè)诿钚锌梢钥吹剑?/p>

Url {
  protocol: null,
  slashes: null,
  auth: null,
  host: null,
  port: null,
  hostname: null,
  hash: null,
  search: "?userid=xiaoqingnian&callback=jsonpcallback",
  query: { userid: "xiaoqingnian", callback: "jsonpcallback" },
  pathname: "/",
  path: "/?userid=xiaoqingnian&callback=jsonpcallback",
  href: "/?userid=xiaoqingnian&callback=jsonpcallback" }

經(jīng)過服務(wù)器端jsonp處理,然后返回一個(gè)函數(shù):

jsonpcallback({"name":"zhaomenghuan","age":"22"})

而我們?cè)陧撁嬷卸x了一個(gè)jsonpcallback()的方法,所以當(dāng)我們?cè)谡?qǐng)求頁面動(dòng)態(tài)生成script調(diào)用服務(wù)器地址,這樣相當(dāng)于在頁面執(zhí)行了下我們定義的函數(shù)。jsonp的實(shí)現(xiàn)原理主要是script標(biāo)簽src可以跨域執(zhí)行代碼,類似于你引用js庫,然后調(diào)用這個(gè)js庫里面的方法;這是這里我們可以認(rèn)為反過來了,你是在本地定義函數(shù),調(diào)用的邏輯通過服務(wù)器返回的一個(gè)函數(shù)執(zhí)行了,所以jsonp并沒有什么神奇的,和XMLHttpRequest、ajax半毛錢關(guān)系都沒有,而且JSONP需要服務(wù)器端支持,始終是無狀態(tài)連接,不能獲悉連接狀態(tài)和錯(cuò)誤事件,而且只能走GET的形式。

node 處理 post 請(qǐng)求實(shí)例

當(dāng)然這里我們可以直接在后臺(tái)設(shè)置響應(yīng)頭進(jìn)行跨域(CORS),如:

var http = require("http");    // 提供web服務(wù)
var query = require("querystring");    // 解析POST請(qǐng)求

http.createServer(function(req,res){
      // 報(bào)頭添加Access-Control-Allow-Origin標(biāo)簽,值為特定的URL或"*"(表示允許所有域訪問當(dāng)前域)
      res.setHeader("Access-Control-Allow-Origin","*");
      
      var postdata = "";
      // 一旦監(jiān)聽器被添加,可讀流會(huì)觸發(fā) "data" 事件
    req.addListener("data",function(chunk){
        postdata += chunk;
    })
    // "end" 事件表明已經(jīng)得到了完整的 body
    req.addListener("end",function(){
        console.log(postdata);     // "appid=xiaoqingnian"
        // 將接收到參數(shù)串轉(zhuǎn)換位為json對(duì)象
        var params = query.parse(postdata);
        if(params.userid == "xiaoqingnian"){
            res.end("{"name":"zhaomenghuan","age":"22"}");
        }
    })
    
}).listen(8080);

我們通過流的形式接收前端post傳遞的參數(shù),通過監(jiān)聽data和end事件,后面在講解event模塊的時(shí)候再深入探究。

CORS默認(rèn)只支持GET/POST這兩種http請(qǐng)求類型,如果要開啟PUT/DELETE之類的方式,需要在服務(wù)端在添加一個(gè)"Access-Control-Allow-Methods"報(bào)頭標(biāo)簽:

res.setHeader(
      "Access-Control-Allow-Methods",
      "PUT, GET, POST, DELETE, HEAD, PATCH"
);

前端訪問代碼如下:

var xhr = new XMLHttpRequest();
xhr.onload = function () {
    console.log(this.responseText);
};
xhr.onreadystatechange = function() {
    console.log(this.readyState);
};

xhr.open("post", "http://127.0.0.1:8080", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send("userid=xiaoqingnian");
url 模塊API詳解 url.parse——解析url字符串

上述代碼中比較關(guān)鍵的是我們通過url.parse方法將url字符串轉(zhuǎn)成Url對(duì)象,用法如下:

url.parse(urlStr, [parseQueryString], [slashesDenoteHost])

接收參數(shù):

urlStr:url字符串

parseQueryString:參數(shù)為true時(shí),query會(huì)被解析為JSON格式,否則為普通字符串格式,默認(rèn)為false;如:

參數(shù)為true:query: { userid: "xiaoqingnian", callback: "jsonpcallback" }

參數(shù)為false:query: "userid=xiaoqingnian&callback=jsonpcallback"

slashesDenoteHost:默認(rèn)為false,當(dāng)url是 ‘http://’ 或 ‘ftp://’ 等標(biāo)志的協(xié)議前綴打頭的,或直接以地址打頭,如 ‘127.0.0.1’ 或 ‘localhost’ 時(shí)候是沒有區(qū)別的;當(dāng)且僅當(dāng)以2個(gè)斜杠打頭的時(shí)候,比如 ‘//127.0.0.1’ 才有區(qū)別。這時(shí)候,如果其值為true,則第一個(gè)單個(gè) ‘/’ 之前的部分被解析為 ‘host’ 和 ‘hostname’,如 ” host : ‘127.0.0.1’ “,如果為false,包括2個(gè)反斜杠在內(nèi)的所有字符串被解析為pathname。如:

> url.parse("http://www.foo/bar",true,true)
Url {
  protocol: null,
  slashes: true,
  auth: null,
  host: "www.foo",
  port: null,
  hostname: "www.foo",
  hash: null,
  search: "",
  query: {},
  pathname: "/bar",
  path: "/bar",
  href: "http://www.foo/bar" }
> url.parse("http://www.foo/bar",true,false)
Url {
  protocol: null,
  slashes: null,
  auth: null,
  host: null,
  port: null,
  hostname: null,
  hash: null,
  search: "",
  query: {},
  pathname: "http://www.foo/bar",
  path: "http://www.foo/bar",
  href: "http://www.foo/bar" }

這里的URL對(duì)象和瀏覽器中的location對(duì)象類似,location中如果我們需要使用類似的方法,我們需要自己構(gòu)造。

url.format——格式化URL對(duì)象

我們可以通過url.format方法將一個(gè)解析后的URL對(duì)象格式化成url字符串,用法為:

url.format(urlObj)

例子:

url.format({
  protocol: "http:",
  slashes: true,
  auth: "user:pass",
  host: "host.com:8080",
  port: "8080",
  hostname: "host.com",
  hash: "#hash",
  search: "?query=string",
  query: "query=string",
  pathname: "/p/a/t/h",
  path: "/p/a/t/h?query=string",
  href: "http://user:[email protected]:8080/p/a/t/h?query=string#hash" 
})

結(jié)果為:
"http://user:[email protected]:8080/p/a/t/h?query=string#hash"
url.resolve——拼接url字符串

我們可以通過url.resolve為URL或 href 插入 或 替換原有的標(biāo)簽,接收參數(shù):
from源地址,to需要添加或替換的標(biāo)簽。

url.resolve(from, to)

例子為:

url.resolve("/one/two/three", "four")
=> "/one/two/four"
url.resolve("http://example.com/", "/one")    
=> "http://example.com/one"
url.resolve("http://example.com/one", "/two") 
=> "http://example.com/two"
Query String 模塊Query String querystring.escape——字符串編碼
querystring.escape("appkey=123&version=1.0.0+")
// "appkey%3D123%26version%3D1.0.0%2B"
querystring.unescape——字符串解碼
querystring.unescape("appkey%3D123%26version%3D1.0.0%2B")
// "appkey=123&version=1.0.0+"
querystring.stringify(querystring.encode)——序列化對(duì)象
querystring.stringify(obj[, sep][, eq][, options])
querystring.encode(obj[, sep][, eq][, options])

接收參數(shù)

obj: 欲轉(zhuǎn)換的對(duì)象

sep:設(shè)置分隔符,默認(rèn)為 ‘&"

eq:設(shè)置賦值符,默認(rèn)為 ‘="

querystring.stringify({foo: "bar", baz: ["qux", "quux"], corge: ""})
// "foo=bar&baz=qux&baz=quux&corge="

querystring.stringify({foo: "bar", baz: ["qux", "quux"], corge: ""},",",":")
// "foo:bar,baz:qux,baz:quux,corge:"
querystring.parse(querystring.decode)——解析query字符串
querystring.parse(str[, sep][, eq][, options])
querystring.decode(str[, sep][, eq][, options])

接收參數(shù)

str:欲轉(zhuǎn)換的字符串

sep:設(shè)置分隔符,默認(rèn)為 ‘&"

eq:設(shè)置賦值符,默認(rèn)為 ‘="

[options] maxKeys 可接受字符串的最大長度,默認(rèn)為1000

querystring.parse("foo=bar&baz=qux&baz=quux&corge=")
// { foo: "bar", baz: [ "qux", "quux" ], corge: "" }

querystring.parse("foo:bar,baz:qux,baz:quux,corge:",",",":")
{ foo: "bar", baz: [ "qux", "quux" ], corge: "" }
node http模塊發(fā)起請(qǐng)求

平時(shí)喜歡看博客,畢竟買書要錢而且有時(shí)候沒有耐心讀完整本書,所以很喜歡逛一些網(wǎng)站,但是很多時(shí)候把所有的站逛一下又沒有那么多時(shí)間,哈哈,所以就準(zhǔn)備把常去的網(wǎng)站的文章爬出來做一個(gè)文章列表,一來省去收集的時(shí)間,二來借此熟悉熟悉node相關(guān)的東西。這里我們首先看一個(gè)爬蟲的小例子,下面以SF為例加以說明(希望不要被封號(hào))。

http.request與http.get的區(qū)別 http.request(options, callback)

options可以是一個(gè)對(duì)象或一個(gè)字符串。如果options是一個(gè)字符串, 它將自動(dòng)使用url.parse()解析。http.request() 返回一個(gè) http.ClientRequest類的實(shí)例。ClientRequest實(shí)例是一個(gè)可寫流對(duì)象。如果需要用POST請(qǐng)求上傳一個(gè)文件的話,就將其寫入到ClientRequest對(duì)象。使用http.request()方法時(shí)都必須總是調(diào)用req.end()以表明這個(gè)請(qǐng)求已經(jīng)完成,即使響應(yīng)body里沒有任何數(shù)據(jù)。如果在請(qǐng)求期間發(fā)生錯(cuò)誤(DNS解析、TCP級(jí)別的錯(cuò)誤或?qū)嶋HHTTP解析錯(cuò)誤),在返回的請(qǐng)求對(duì)象會(huì)觸發(fā)一個(gè)"error"事件。

Options配置說明:

host:請(qǐng)求發(fā)送到的服務(wù)器的域名或IP地址。默認(rèn)為"localhost"。

hostname:用于支持url.parse()。hostname比host更好一些

port:遠(yuǎn)程服務(wù)器的端口。默認(rèn)值為80。

localAddress:用于綁定網(wǎng)絡(luò)連接的本地接口。

socketPath:Unix域套接字(使用host:port或socketPath)

method:指定HTTP請(qǐng)求方法的字符串。默認(rèn)為"GET"。

path:請(qǐng)求路徑。默認(rèn)為"/"。如果有查詢字符串,則需要包含。例如"/index.html?page=12"。請(qǐng)求路徑包含非法字符時(shí)拋出異常。目前,只否決空格,不過在未來可能改變。

headers:包含請(qǐng)求頭的對(duì)象。

auth:用于計(jì)算認(rèn)證頭的基本認(rèn)證,即"user:password"

agent:控制Agent的行為。當(dāng)使用了一個(gè)Agent的時(shí)候,請(qǐng)求將默認(rèn)為Connection: keep-alive??赡艿闹禐椋?/p>

undefined(默認(rèn)):在這個(gè)主機(jī)和端口上使用[全局Agent][]。

Agent對(duì)象:在Agent中顯式使用passed。

false:在對(duì)Agent進(jìn)行資源池的時(shí)候,選擇停用連接,默認(rèn)請(qǐng)求為:Connection: close。

keepAlive:{Boolean} 保持資源池周圍的套接字在未來被用于其它請(qǐng)求。默認(rèn)值為false

keepAliveMsecs:{Integer} 當(dāng)使用HTTP KeepAlive的時(shí)候,通過正在保持活動(dòng)的套接字發(fā)送TCP KeepAlive包的頻繁程度。默認(rèn)值為1000。僅當(dāng)keepAlive被設(shè)置為true時(shí)才相關(guān)。

http.get(options, callback)

因?yàn)榇蟛糠值恼?qǐng)求是沒有報(bào)文體的GET請(qǐng)求,所以Node提供了這種便捷的方法。該方法與http.request()的唯一區(qū)別是它設(shè)置的是GET方法并自動(dòng)調(diào)用req.end()。

爬蟲實(shí)例

這里我們使用es6的新特性寫:

const https = require("https");
https.get("https://segmentfault.com/blogs", (res) => {
    console.log("statusCode: ", res.statusCode);
      console.log("headers: ", res.headers);
      var data = "";
      res.on("data", (chunk) => {
        data += chunk;
      });
      res.on("end", () => {
          console.log(data);
      })
}).on("error", (e) => {
      console.error(e);
});

這樣一小段代碼我們就可以拿到segmentfault的博客頁面的源碼,需要說明的是因?yàn)檫@里請(qǐng)求的網(wǎng)站是https協(xié)議,所以我們需要引入https模塊,用法同http一致。下面需要做的是解析html代碼,下面我們需要做的就是解析源碼,這里我們可以引入cheerio,一個(gè)node版的類jQuery模塊,npm地址:https://www.npmjs.com/package...。

首先第一步安裝:

npm install cheerio

然后就是將html代碼load進(jìn)來,如下:

var cheerio = require("cheerio"),
var $ = cheerio.load(html);

最后我們就是分析dom結(jié)構(gòu)咯,通過類似于jQuery的方法獲取DOM元素的內(nèi)容,然后就將數(shù)據(jù)重新組裝成json結(jié)構(gòu)的數(shù)據(jù)。這里就是分析源碼然后,這里我就不詳細(xì)分析了,直接上代碼:

function htmlparser(html){
    var baseUrl = "https://segmentfault.com";
    
    var $ = cheerio.load(html);
    var bloglist = $(".stream-list__item");
    
    var data = [];
    
    bloglist.each(function(item){
        var page = $(this);
        var summary = page.find(".summary");
        var blogrank = page.find(".blog-rank");
        
        var title = summary.find(".title a").text();
        var href = baseUrl + summary.find(".title a").attr("href");
        var author = summary.find(".author li a").first().text().trim();
        var origin = summary.find(".author li a").last().text().trim();
        var time = summary.find(".author li span")[0].nextSibling.data.trim();
        var excerpt = summary.find("p.excerpt").text().trim();
        var votes = blogrank.find(".votes").text().trim();
        var views = blogrank.find(".views").text().trim();
        
        data.push({
            title: title,
            href: href,
            author: author,
            origin: origin,
            time: time,
            votes: votes,
            views: views,
            excerpt: excerpt
        })
    })
    
    return data;
}

結(jié)果如下:

[{ title: "轉(zhuǎn)換流",
    href: "https://segmentfault.com/a/1190000007036273",
    author: "SwiftGG翻譯組",
    origin: "SwiftGG翻譯組",
    time: "1 小時(shí)前",
    votes: "0推薦",
    views: "14瀏覽",
    excerpt: "作者:Erica Sadun,原文鏈接,原文日期:2016-08-29譯者:Darren;校對(duì):shank
s;定稿:千葉知風(fēng) 我在很多地方都表達(dá)了我對(duì)流的喜愛。我在 Swift Cookbook 中介紹了一些?,F(xiàn)
在,我將通過 Pearson 的內(nèi)容更新計(jì)劃..." },
......
]

這里我們只是抓取了文章列表的一頁,如果需要抓取多頁,只需要將內(nèi)容再次封裝一下,傳入一個(gè)地址參數(shù)?page=2,如:https://segmentfault.com/blog...
另外我們也沒有將詳情頁進(jìn)一步爬蟲,畢竟文章的目的只是學(xué)習(xí),同時(shí)方便自己查看列表,這里保留原始地址。

溫馨提示:大家不要都拿sf做測(cè)試哦,不然玩壞了就不好。

模擬登陸

哈哈,寫到這里已經(jīng)很晚了,用node試了試模擬登陸SF,結(jié)果404,暫時(shí)沒有什么思路,等有時(shí)間再試試專門開篇講解咯。這里推薦一篇之前看到的文章:記一次用 NodeJs 實(shí)現(xiàn)模擬登錄的思路。

參考

nodejs官網(wǎng)API文檔

進(jìn)擊Node.js基礎(chǔ)(一)

Node.js v4.2.4 文檔 中文版

文章代碼源碼下載:https://github.com/zhaomenghu...

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/84564.html

相關(guān)文章

  • 次網(wǎng)站的性能優(yōu)化之路 -- 天下武功,唯快不破

    摘要:百度搜索資源平臺(tái)有閃電算法的支持,為了能夠保障用戶體驗(yàn),給予優(yōu)秀站點(diǎn)更多面向用戶的機(jī)會(huì),閃電算法在年月初上線。下欄是每一個(gè)指標(biāo)的細(xì)化性能評(píng)估。最后優(yōu)化之路漫漫,永無止境,天下武功,唯快不破。 showImg(https://segmentfault.com/img/remote/1460000018537491); 首屏作為直面用戶的第一屏,其重要性不言而喻,如何加快加載的速度是非常重...

    mudiyouyou 評(píng)論0 收藏0
  • node爬蟲的升級(jí)打怪之路

    摘要:我是一個(gè)知乎輕微重度用戶,之前寫了一只爬蟲幫我爬取并分析它的數(shù)據(jù),我感覺這個(gè)過程還是挺有意思,因?yàn)檫@是一個(gè)不斷給自己創(chuàng)造問題又去解決問題的過程。所以這只爬蟲還有登陸知乎搜索題目的功能。 我一直覺得,爬蟲是許多web開發(fā)人員難以回避的點(diǎn)。我們也應(yīng)該或多或少的去接觸這方面,因?yàn)榭梢詮呐老x中學(xué)習(xí)到web開發(fā)中應(yīng)當(dāng)掌握的一些基本知識(shí)。而且,它還很有趣。 我是一個(gè)知乎輕微重度用戶,之前寫了一只爬...

    shiweifu 評(píng)論0 收藏0
  • Node.js學(xué)習(xí)之路11——?jiǎng)?chuàng)建TCP客戶端

    摘要:創(chuàng)建客戶端對(duì)象與服務(wù)器的參數(shù)屬性一樣此時(shí)端口有下邊的幾個(gè)屬性連接另一端所使用的遠(yuǎn)程地址連接另一端所使用的端口號(hào)本地用于建立連接的地址本地用于建立連接的端口號(hào)端口對(duì)象可以被用來寫入向客戶端或服務(wù)器端發(fā)送的流數(shù)據(jù)當(dāng)流數(shù)據(jù)被寫入后將立即發(fā)送到客戶 1. 創(chuàng)建TCP客戶端 const net = require(net); let socket = new net.Socket([option...

    cnsworder 評(píng)論0 收藏0
  • 「真?全棧之路」Web前端開發(fā)的后端指南

    前言 在若干次前的一場(chǎng)面試,面試官看我做過python爬蟲/后端 的工作,順帶問了我些后端相關(guān)的問題:你覺得什么是后端? 送命題。當(dāng)時(shí)腦瓦特了,答曰:邏輯處理和數(shù)據(jù)增刪改查。。。 showImg(https://user-gold-cdn.xitu.io/2019/4/24/16a4ed4fc8c18078); 當(dāng)場(chǎng)被懟得體無完膚,羞愧難當(dāng)。事后再反思這問題,結(jié)合資料總結(jié)了一下。發(fā)現(xiàn)自己學(xué)過的Re...

    chuyao 評(píng)論0 收藏0
  • Node.js學(xué)習(xí)之路25——Express的request對(duì)象

    摘要:對(duì)象表示請(qǐng)求并且具有請(qǐng)求查詢字符串參數(shù)正文標(biāo)題頭等屬性對(duì)應(yīng)用程序?qū)嵗囊帽4媪撕芏鄬?duì)使用中間件的應(yīng)用程序?qū)嵗囊脪燧d在路由實(shí)例上的路徑請(qǐng)求主體和和包含在請(qǐng)求正文中提交的數(shù)據(jù)的鍵值對(duì)默認(rèn)情況下它是未定義的當(dāng)您使用體解析中間件如和時(shí)將被填 2. request req對(duì)象表示http請(qǐng)求,并且具有請(qǐng)求查詢字符串,參數(shù),正文,http標(biāo)題頭等屬性 app.get(/user/:id, ...

    cocopeak 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<