1205-http模块动态API路由匹配 & 跨域请求处理(jsop cors)

http模块实现API路由

// /getUser  /getOneUser  /removeUser /addUser /updateUser
//统一收拢为 /user,通过method区分
//method:GET获取   POST增加  PUT更新  DELETE删除     OPTIONS(试探性请求)

// /getUser      /user         get
// /getOneUser   /user?id=1    get
// /removeUser   /user?id=1    delete
// /addUser      /user         post  {username:xxx,password:xxx}
// /updateUser   /user

// RESTFUL 接口风格,不是标准,通过http请求method动词区分:
//查询某一个用户返回查询到的一项{username:xxx}
//查询所有,返回的是数组类型
//添加返回添加的那一项
//修改,返回修改的那一项
//删除 返回控对象

/*
req.headers  请求头,都是小写的
 { host: 'localhost:3002',
   connection: 'keep-alive',
   'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36',
   accept: '*/*',
    referer: 'http://localhost:3002/',
    'accept-encoding': 'gzip, deflate, br',
    'accept-language': 'zh-CN,zh;q=0.9'
    }
req.url 请求的路径,需要用url.parse处理成对象
req.method  请求的方式,都是大写的,GET获取   POST增加  PUT更新  DELETE删除     OPTIONS(试探性请求)
post接收参数,是读取req可读流的方式接收,req是可读流,on('data') on('end')

*/
//通过动态匹配,实现用户的增删改查api
let http = require('http');
let port = 3002;
let path = require('path');
let url  = require('url')
let mime = require('mime');
let users = [{username:'小明',password:'1231',id:1},{username:'小u',password:'1231',id:2}]
http.createServer((req,res)=>{
    let {pathname,query} = url.parse(req.url,true);
    if(pathname =='/user'){
        let id = query.id;
        switch(req.method){
            case "GET":
                res.setHeader('Content-Type',"application/javascript;charset=utf-8")
                if(!id){//获取所有
                    res.end(JSON.stringify(users))
                }else{//获取单个 
                    let user = users.find(item=>item.id==id)
                    if(typeof user !='undefined'){
                         res.end(JSON.stringify(user))
                    }else{
                        res.end(JSON.stringify({}))
                    }
                }
                break;
                
            case "POST"://添加用户
                res.setHeader("Content-Type","application/json;charset=utf-8");
                //post接收参数,req是可读流,用事件接收。
                let str = "";
                req.on('data',chunk=>{
                    str += chunk;//chunk是buffer,字符串拼接,会自动调用toString(),这种可能出现乱码,目前不用考虑,因为每次默认读取的都是64k,不会出现断码。
                })
                req.on('end',()=>{
                    let user = JSON.parse(str)
                    user.id = users.length ? users[users.length-1].id + 1 : 1;
                    users.push(user)
                    res.end(JSON.stringify(user))
                })
                
                break;
            
            case "DELETE"://删除某个
                if(id){
                    users = users.filter((item)=>item.id!=id);
                    res.end(JSON.stringify({}))
                }
                break;
        }
        
        return ;
    }
})

复制代码

跨域处理

  • jsonp
//jsonp就是利用script 的src 不受同源策略影响,动态向页面插入script标签,实现请求。
//注意:需要和后端协商好callback的key是啥。

前端页面js:
function setData(data){
    console.log(data);//获取到数据
}
let script = document.createElement('script');
script.src = "http://localhost:3002/jsonp?cb=setData"
document.body.appendChild(script);

后端api:
let http = require('http');
let port = 3002;
let fs = require('fs');
let path = require('path')
let url = require('url')
let mime = require('mime');
http.createServer((req, res) => {
    let {pathname, query} = url.parse(req.url, true);
    if (pathname == '/jsonp') {
       let school = JSON.stringify({name:'zfpx'});
       // res.end(`var a  = ${school}`) //在前端的全局作用域就可以获取到 变量a
        res.end(`${query.cb}(${school})`)//返回一个全局方法执行
        return ;
    }
    })
}).listen(port, () => {
    console.log(`${port} 服务器启动`)
});


复制代码
  • cors
//通过后端设置响应头,来允许访问源进行访问,和允许支持访问的请求方式,解决跨域问题


let http = require('http');
let port = 3002;
let fs = require('fs');
let path = require('path')
let url = require('url')
let mime = require('mime');
let users = [{username: '乔石', password: 'admin', id: 1}, {username: 'zfpx', password: 'admin', id: 2}];
http.createServer((req, res) => {
    let {pathname, query} = url.parse(req.url, true);
    // 跨域设置请求头
    res.setHeader('Access-Control-Allow-Origin',"*");//设置允许访问的源,这样ajax跨域请求就不会报错了。
    res.setHeader('Access-Control-Allow-Methods','GET,POST,PUT,DELETE,OPTIONS');
    //如果是跨域请求会先收到一个浏览器发的options试探性请求,主要用来看服务器支持那些方法请求和 服务器是否联通
    if(req.method =='OPTIONS'){
        res.end('ok')
        return;
    }

    if(pathname == '/clock'){
        res.end('2017.11.19');
        return;

    }
    //处理静态资源文件
    fs.stat(`.${pathname}`, (err, stats) => {
        if (err) {
            res.statusCode = 404;
            res.end(`${pathname} is not found`);
            return;
        }
        if (stats.isFile()) {
            mime.getType(pathname)
            res.setHeader('Content-Type', mime.getType(pathname) + ';charset=utf-8');
            fs.createReadStream(`.${pathname}`).pipe(res);
        }
        if (stats.isDirectory()) {
            res.setHeader('Content-Type', 'text/html;charset=utf-8');
            let p = path.join(`.${pathname}`, './index.html');
            fs.createReadStream(p).pipe(res)
        }

    })
}).listen(port, () => {
    console.log(`${port} 服务器启动`)
});

    
复制代码
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值