CORS和JSONP跨域资源共享

本文介绍了如何使用Express创建RESTful API,并详细讲解了CORS解决跨域问题的方法,包括简单请求和预检请求的区别,以及JSONP的原理和应用场景。

使用Express写接口

1.创建基本服务器

// 引入 express 模块
const express = require(`express`)

// 实例化express服务器
const jojo = express()

// 引入自己的路由模块
const router = require(`./apiRot.js`)

// 注册路由模块
jojo.use(`/user`, router)

//在3000接口开启服务器
jojo.listen(3000, () => {
    console.log(`服务器启动于http://127.0.0.1:3000`);
})

2.创建API路由模块

//引入express模块
const express = require(`express`)

//实例化路由对象
const router = express.Router()

//配置 express.urlencoded 中间件
router.use(express.urlencoded({ extended: false }))

// 编写get接口
router.get(`/get/:age`, (req, res) => {
    //通过req.params对象,可以访问到URL中通过 : 匹配到的动态参数.
    const qur = req.params
    
    res.send({
        status: 0, //0 表示成功 1 表示失败
        message: `GET请求成功!`, // 状态描述
        data: qur // 响应给客户端的数据
    })
})

router.get(`/get`, (req, res) => {
    //通过req.query对象,可以访问到客户端通过查询字符串形式发送到客户端的参数
    const qur = req.query

    res.send({
        status: 0, //0 表示成功 1 表示失败
        message: `GET请求成功!`, // 状态描述
        data: qur // 响应给客户端的数据
    })
})


router.post(`/post`, (req, res) => {
    //获取客户端通过请求体,发送到服务器的 URL-encoded 数据
    const body = req.body
    res.send({
        status: 0, //0 表示成功 1 表示失败
        message: `POST请求成功!`, // 状态描述
        data: body // 响应给客户端的数据
    })
})

//向外暴露router对象
module.exports = router

如果要获取URL-encoded格式的请求体数据,必须配置中间件 app.use(express.urlencoded({ extended: false }))

以上代码在未解决跨域的情况下直接使用会在浏览器控制台报跨域的错误!!!!

解决办法的方案有两种:

1.CORS(主流方案,推荐)

2.JSONP(有缺陷,只支持GET请求)

使用CORS中间件解决跨域

先介绍CORS方法:

cors 是 Express 的一个第三方中间件。通过安装和配置 cors 中间件,可以很方便地解决跨域问题。 使用步骤分为如下 3 步:

① 运行 npm install cors 安装中间件

② 使用 const cors = require('cors') 导入中间件

③ 在路由之前调用 app.use(cors()) 配置中间件

至于什么是CORS,详情可见下面的博客:链接如下

http://www.ruanyifeng.com/blog/2016/04/cors.html

CORS请求分类

客户端在请求 CORS 接口时,根据请求方式和请求头的不同,可以将 CORS 的请求分为两大类,分别是:

①简单请求

  • 同时满足以下两大条件的请求,就属于简单请求:

  • ① 请求方式:GET、POST、HEAD 三者之一

  • ② HTTP 头部信息不超过以下几种字段:无自定义头部字段、Accept、Accept-Language、Content-Language、DPR、 Downlink、Save-Data、Viewport-Width、Width 、Content-Type(只有三个值application/x-www-form-urlencoded、multipart/form-data、text/plain)

②预检请求

  • 只要符合以下任何一个条件的请求,都需要进行预检请求:

  • ① 请求方式为 GET、POST、HEAD 之外的请求 Method 类型

  • ② 请求头中包含自定义头部字段

  • ③ 向服务器发送了 application/json 格式的数据

在浏览器与服务器正式通信之前,浏览器会先发送 OPTION 请求进行预检,以获知服务器是否允许该实际请求,所以这一 次的 OPTION 请求称为“预检请求”。服务器成功响应预检请求后,才会发送真正的请求,并且携带真实数据。

简单请求和预检请求的区别

简单请求的特点:客户端与服务器之间只会发生一次请求

预检请求的特点:客户端与服务器之间会发生两次请求,OPTION 预检请求成功之后,才会发起真正的请求

JSONP跨域资源共享

首先,JSONP不属于真正的ajax请求,它是通过script标签的src属性来请求服务器上的数据,同时服务器响应一个函数调用携带数据,这种请求方式叫JSONP.

特点:

① JSONP 不属于真正的 Ajax 请求,因为它没有使用 XMLHttpRequest 这个对象。

② JSONP 仅支持 GET 请求,不支持 POST、PUT、DELETE 等请求。

使用JSONP接口的注意事项:

如果项目中已经配置了CORS,为了防止冲突,必须在CORS中间件之前声明JSONP接口,不然JSONP接口就会被解析成CORS接口!

JSONP跨域资源共享

首先,JSONP不属于真正的ajax请求,它是通过script标签的src属性来请求服务器上的数据,同时服务器响应一个函数调用携带数据,这种请求方式叫JSONP.

特点:

① JSONP 不属于真正的 Ajax 请求,因为它没有使用 XMLHttpRequest 这个对象。

② JSONP 仅支持 GET 请求,不支持 POST、PUT、DELETE 等请求。

使用JSONP接口的注意事项:

如果项目中已经配置了CORS,为了防止冲突,必须在CORS中间件之前声明JSONP接口,不然JSONP接口就会被解析成CORS接口!

实现JSONP接口的步骤

//
app.get(`/jsonp`, (req, res) => {
     //获取服务器返回的回调函数的名字
    const { callback } = req.query
    
    //返回给服务器的数据
    const obj = {
        uname: `卢本伟`,
        age: 18,
        sex: `男`
    }
   // JSON.stringify(obj)因为浏览器只能接收字符串,所以把数据转化成json格式的字符串 以函数调用的方式返回给客户端
    res.send(`${callback}(${JSON.stringify(obj)})`)
})

html中调用ajax函数,发送jsonp请求:

$(`#jsonp`).on(`click`, function () {
        $.ajax({
            method: `get`,
            dataType: `jsonp`,//一定要写,表示要发起jsonp请求!!!
            url: `http://127.0.0.1:3000/user/jsonp`,
            success: (res) => {
                console.log(res);
            }
        })
    })

成功会在控制台打印如下信息:

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值