nodejs使用静态服务器处理ajax

作者: 枸杞辣条 | 来源:发表于2017-04-11 00:06 被阅读752次

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

    上一次,手写了一个静态服务器这次我们想更进一步:返回给前端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不用特殊处理跟之前保持一致就好。

    最后:

    最后

    相关文章

      网友评论

        本文标题:nodejs使用静态服务器处理ajax

        本文链接:https://www.haomeiwen.com/subject/kyjxattx.html