目 录CONTENT

文章目录

Express补充

Administrator
2020-07-24 / 0 评论 / 0 点赞 / 9259 阅读 / 8932 字 / 正在检测是否收录...

Express补充

Express返回json

express的resp可以渲染对象,也可以send字符串,我们可以将一个对象通过JSON.stringify()序列化成json字符串以后再通过resp.send()发送到页页去

如果前端需要我们设置CORS跨域的时候,服务器应该怎么设置呢

app.js代码

app.get("/getList", (req, resp) => {
    let obj = {
        userName: "杨标",
        sex: "男",
        age: 18,
        hobby: ["看书", "睡觉"]
    };
    let jsonStr=JSON.stringify(obj);   //将对象序列化成json字符串
    resp.setHeader("Access-Control-Allow-Headers","Content-Type");
    resp.setHeader("Access-Control-Allow-Methods","GET,POST,PUT,DELETE,OPTIONS");
    resp.setHeader("Access-Control-Allow-Origin","*");
    resp.send(jsonStr);
});

在服务器里面,我们将得到的obj对象通过JSON.stringify(obj)变成了json字符串,然后调用resp.send()的方法发送到的浏览器,浏览器通过 ajax接收到的就是一个json字符串,它是一个 string,如果需要使用,需要在浏览器调用JSON.parse()重新转化成js对象

浏览器代码

$(function(){
    $("#btn1").click(function(){
        $.get("http://127.0.0.1:8888/getList",function(data){
            // data 就是服务器返回的数据
            console.log(data);
            console.log(typeof data);   //string 
            //如果要拿到里面的属性,应该怎么办
            var jsonObj = JSON.parse(data);
            console.log(typeof jsonObj);   //object
            console.log(jsonObj.userName);
        });
    });
})

在之前我们使用Ajax请求的时候,我们返回的都是一个对象,不需要我们调用JSON.parse()的方法去转换。现在我们的服务器为什么不行呢

1571035567600

通过上面的图,我们可以看一以,在服务器里面,我们把对象转成JSON字符串,而在浏览器里面,我们又把JSON字符串成了对象

当我们如果在调用resp.send()返回之前,如果添加了如下的响应头

resp.setHeader("Content-Type","application/json");

则前端在接收到的时候,数据会自动的做一次JSON.parse()的转换,这个时候,得到的就是一个js对象

添加请求头以后的代码

app.get("/getList2",(req,resp)=>{
    let obj = {
        userName: "杨标",
        sex: "男",
        age: 18,
        hobby: ["看书", "睡觉"]
    };
    resp.setHeader("Access-Control-Allow-Headers","Content-Type");
    resp.setHeader("Access-Control-Allow-Methods","GET,POST,PUT,DELETE,OPTIONS");
    resp.setHeader("Access-Control-Allow-Origin","*");
    let jsonStr=JSON.stringify(obj);   //将对象序列化成json字符串
    //添加一个响应类型 
    resp.setHeader("Content-Type","application/json");
    resp.send(jsonStr);
});

所以通过Ajax去接收的时候,一定要注意返回的数据到底是什么类型,如果是JSON字符串,则要手动的做一次转换,如果是对象则不用转了

这一种方式虽然简化了前面的操作,但在是在Express里面又多了一步操作,所以Express考虑到这种情况以后,直接推了一个新的方法resp.json();

app.get("/getList3",(req,resp)=>{
    let obj = {
        userName: "杨标",
        sex: "男",
        age: 18,
        hobby: ["看书", "睡觉"]
    };
    resp.setHeader("Access-Control-Allow-Headers","Content-Type");
    resp.setHeader("Access-Control-Allow-Methods","GET,POST,PUT,DELETE,OPTIONS");
    resp.setHeader("Access-Control-Allow-Origin","*");
    //没有设置请头,直接把对象放了进去
    resp.json(obj);
})

resp.json()这个方法相当于把对象序列化成JSON字符串以后然后再给它添加一个application/json的请求头,这个前端在接收到数据的时候,就直接是一个对象了,不需要在转换了

这种操作既方便了后端,也方便了前端。所以后期在Express里面需要返回一个JSON字符串到前端去的时候,可以调用这个方法

通过拦截器来设置请求头

在上面的三个请求里面, 我们每次都设置了跨域的请求头,这样很麻烦 ,我们可以利用之前学习的Express拦截器来完成这个操作

//添加一个拦截器,给响应的请求添加请求头
app.use((req,resp,next)=>{
    resp.setHeader("Access-Control-Allow-Headers","Content-Type");
    resp.setHeader("Access-Control-Allow-Methods","GET,POST,PUT,DELETE,OPTIONS");
    resp.setHeader("Access-Control-Allow-Orogin","*");
    //放行
    next();
})

只需要所有的请求前面添加上面的拦截器,这样所有请求的返回就都可以添加上面的请求头了


Express的请求方式

就目前我们所学习的app与路由的处理请求方式里面,有app.get(),app.post()

express里面,get请求的参数通过req.query的方式获取,post请求的方式req.body

router.get("/List",(req,resp)=>{
    console.log(req.query);
})
router.post("/List",(req,resp)=>{
    console.log(req.body);
});

不同的请求方式对应不同的取值方式

路径变量pathVariable

字变意义理解就是把变量放在请求路径里面去

router.get("/checkSid/:sid",(req,resp)=>{
    let arr=["1001","1002","1003"];
    // let sid=req.params.sid;
    let {sid}=req.params;
    console.log(sid);
    resp.send(arr.includes(sid));
})

这个时候,前端的请求地址就应该变成 http://127.0.0.1:8888/StuInfo/checkSid/1001,最后面的1001代表路径变量参数:sid

路径变量的参数取值使用req.params来进行

路径变量还可以放多个参数

router.get("/checkSid/:sid/:userName",(req,resp)=>{
    let arr=["1001","1002","1003"];
    // let sid=req.params.sid;
    let {sid,userName}=req.params;
    console.log(sid);
    console.log(userName);
    resp.send(arr.includes(sid));
})

请求的url为http://127.0.0.1:8888/StuInfo/checkSid/1001/yangbiao

优点

  1. 定义了参数以后必须要传递参数,如果不传,找不到路径,报404错误
  2. 这一种请求方式既可以以路径变量的方式向后台传值 ,也可以以post的方式向后后,一次请求,两种传递方式。如下代码所示
router.post("/doCheckSid/:sid/:userName",(req,resp)=>{
    console.log(req.params);
    console.log(req.body);
    resp.send("我收到你的数据了");
});

这个地方的 sid与userName是通过路径变量传递过来的,而后面的其它参数则是通过post传递过来的

1571041259950


Express的多功能请求方式

当一个路由需要通过多各请求方式接收路径请求的时候,我们建议它使用all的方法。如下代码

router.all("/test",(req,resp)=>{
    // console.log(req.query.sid);
    let sid = req.param("sid");
    let sname=req.param("sname");
    console.log(sid,sname);
    resp.send("我收到test的数据了");
});

all可以接收所有的请求类型,但是在接收值的方面,我们更建议使用 req.param() 的方法来接值,这种接值是不针对请求方式,只要你传值了,无论以何种方式进来的,一定可以接收到

Express接收前端传值总结

传值方式服务器接收值方式备注
router.get("/List")req.query
router.post("/List")req.body
router.get("/List/:sid")req.paramspathVariable具体参照上个章节
router.all("/List")req.param()这是一个方法,可以接收任何方式传过来的值

Express实现中转服务器

在前端的ajax请求里面,我们的ajax是不允许跨域请求数据的,这个时候,我们可以使用nodejs来进行一次中转操作

第一步:创建路由

app.use("/maoyanApi",require("./routes/maoyanApiRoute"));

第二步:在路由里建议代理

const router=require("express").Router();
const axios=require("axios");

let baseURL="http://m.maoyan.com";  //原始的地址就是这一个
router.all(/\/.*/,async (req,resp)=>{
    let method=req.method;    //得到请求方式
    let url = req.url;   //这个地址不包含路由的路径 maoyanApi
    let result=null;
    if(method.toUpperCase()=="GET"){
       result = await axios.default.get(baseURL+url,{
           responseType:"stream"
       });
    }
    else if(method.toUpperCase()=="POST"){
        result= await axios.default.post(baseURL+url,req.body,{
            responseType:"stream"
        });
    }
    // resp.send(JSON.stringify(result.data));
    result.data.pipe(resp);
});

module.exports=router;
  • router.all()代表接收所有的请求方式
  • /\/.*/这个正则代表接收所有的请求路径
  • 使用流的方式响应数据,然后以流的信息直接对接到resp 上面

当代码完成以后,我们就可以实现请求代理了

新地址

http://127.0.0.1:8888/maoyanApi/ajax/comingList?token=

原地址

http://m.maoyan.com/ajax/comingList?token=
0

评论区