nodejs使用静态服务器处理ajax

如需转载请注明来源与作者

上一次,手写了一个静态服务器这次我们想更进一步:返回给前端ajax数据。注意:这里只是一个演示,所以所有ajax传入服务器的数据,我不会经过处理直接返回

文件夹

Tips :

fs.readFile(url,'utf8',(error,data)=>{
            response.end(data);
      })

上次使用的是utf-8编码格式来读取文件,但是这样设置遇到返回图片就会报错。所以,我们可以删除utf8这个字段,这样才能成功返回图片。

  • 预处理:

  1. 首先文件夹的服务器文件处理也就是APP文件夹。应该进行进一步的抽离。
  2. 使用Promise作连接。
    3.png

    这样做能让模块之间相互独立又相互连接,使代码更好维护
    接着我们把APP(APP/index.js)的枢纽进行整合:
let path = require('path')
let fs = require('fs')
let staticServer = require('./static-server');
class APP {
      initSever() {
            return (request, response) => {
                  let {url} = request;
                  staticServer(url).then((data)=>{  
                   //这里staticServer返回的是一个promise
                        response.writeHead(200,'resolve ok',{'X-powered-by': 'Node.js'})  
                  //标记一下返回头
                        response.end(data);
                  })
            }
      }
}
module.exports = APP

静态服务器(APP/static-server/index.js)的处理:

let fs = require('fs');
let path = require('path');
//对url进行处理让它能够定位到public下面的资源
let getPath = (url) => {  
    let urlHeader = './public'
    return path.resolve(process.cwd(), urlHeader + url)
}
module.exports = (url) => {
    return new Promise((resolve, reject) => {
        if (url === '/') url = '/index.html';
        url = getPath(url)
        fs.readFile(url, (error, data) => {  
//如果你不使用Promise的话,你可以使用fs,readFileSync进行同步的处理
            resolve(data)
        })
    })
}

在前端代码引入jq与js,写点ajax

$.get({
    url : 'user.action', //给每个ajax的请求后缀添加'.action'以作标识
    dataType : 'json'
}).done(function(data){
    console.log(data) //在这里我们直接打出数据
})
  • get方法的处理

api-server

let msgMap = {
    '/user.action' : {
        pet : 'dog',
        color : 'white'
    }
}
let data  ='';
module.exports= (req)=>{
    let {url} = req; // 这里先传req,接下来处理post会用到
    data = msgMap[url];  //判断该url在映射表里面是否有对应的信息
    return Promise.resolve(JSON.stringify(data)) 
//必须转换成字符串,否则response.end的第一个参数必须是字符串或者buffer
}
//上述代码运行成功后console打出的应该是一个对象。

APP/index.js的修改:

class APP {
      initSever() {
            return (request, response) => {
                  let {url} = request;
                  apiServer(request).then((val) => {
                    //一个url进入服务器先在apiServer里面进行一个判断,
                   //返回出来的值如果是一个undefined就走静态资源路线
                   //否则就是ajax请求,直接返回给前端。
                              if (val) {
                                    return val;
                              } else {
                                    return staticServer(url)
                              }
                        })
                        .then((data) => {  
                     //这里是用来把数据返回给前端的地方,在这一块主要是处理返回头。
                              response.writeHead(200, 'resolve ok', {
                                    'X-powered-by': 'Node.js'
                              })
                              response.end(data);
                        })
            }
      }
}

结果:

  • post方法的处理

  • 由于post比较复杂在这里先讲一下思路

post的处理比get的处理要烦琐得多。
post请求,我们往往是要传递数据给服务器。前端返回给后端服务器的形式是用stream的形式,所以我们可以在request对象上获取前端返回的数据。
返回数据的处理:由于中文在stream传输的过程是以buffer形式,所以会造成字符串丢失,所以我们需要使用Buffer.concat进行字符的拼接。

4.png

  • public/js/index.js添加:
$.ajax({
    method: 'POST',
    url : '/getMsg.action',
    data : JSON.stringify({ //注意这里应该转成字符串否则传到服务器会变成car=BMW&msg=hello world
        car : 'BMW',
        msg : 'hello world'
    }),
    dataType:'json'
}).done(function(data){
    console.log(JSON.parse(data)) //在这里我们直接打出数据
})
  • ·api-server/index.js·
let msgMap = {
    '/user.action': {
        pet: 'dog',
        color: 'white'
    }
}
let data = '';
let info = [];
module.exports = (req) => {
    let {url} = req;
    if (req.method.toLowerCase() === 'get') {  //这一块不多说,处理get请求
        data = msgMap[url];
        return Promise.resolve(JSON.stringify(data))
    } else {
        return new Promise((resolve, reject) => {
            req.on('data', (chunk) => {
             //on类似于jquery添加事件,监听data是否传入数据,该方法在stream对象上
                info.push(chunk)//为什么用数组,为了防止中文数据丢失所以我们把每一个buffer用数组存起来
                 //你也可以直接使用字符串拼接,如:info+=chunk;这样写相当于:info=info.toString() + chunk.toString()
            }).on('end', () => {
                info = Buffer.concat(info).toString(); // Buffer.concat用来拼接所有的buffer
                //在这里你可以处理你想要的数据 doSomething(info) 
                resolve(JSON.stringify(info));//这里我只是把前端的数据拿过来没有做任何的改动直接返回
            })
        })
    }
}
  • APP/index.js不用特殊处理跟之前保持一致就好。

最后:

最后
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,386评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,939评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,851评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,953评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,971评论 5 369
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,784评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,126评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,765评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,148评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,744评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,858评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,479评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,080评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,053评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,278评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,245评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,590评论 2 343

推荐阅读更多精彩内容