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不用特殊处理跟之前保持一致就好。

最后:

最后
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容