CORS 和 JSONP 解决跨域问题

由于浏览器的同源策略,不同协议、域名、端口的网页是不允许互相请求资源的。但在前后端分离的开发模式中,前后端的域名是不一样的,如果要进行数据的交互就会产生跨域。

解决跨域的方案:

一:cors设置请求头

浏览器的同源安全策略默认会阻止网页“跨域”获取资源。但如果接口服务器配置了 CORS 相关的 HTTP 响应头,就可以解除浏览器端的跨域访问限制

  1. CORS 主要在服务器端进行配置。客户端浏览器无须做任何额外的配置,即可请求开启了 CORS 的接口
  2. CORS 在浏览器中有兼容性。只有支持 XMLHttpRequest Level2 的浏览器,才能正常访问开启了 CORS 的服务端接口(例如:IE10+Chrome4+FireFox3.5+
  1. cors 是 Express 的一个第三方中间件。通过安装和配置 cors 中间件,可以很方便地解决跨域问题
  2. 使用步骤
    • 安装中间件: npm install cors
    • 导入中间件: const cors = require('cors')
    • 配置中间件: 在路由之前调用app.use(cors())
  3. 示例代码
   // 导入 express 模块
   const express = require('express')
   
   // 创建 express 的服务器实例
   const app = express()
   
   // 导入中间件
   const cors = require('cors')
   // 配置中间件
   app.use(cors())
   
   // 配置解析表单数据的中间件
   app.use(express.urlencoded({ extended: false }))
   
  // 挂载一个路由
   app.post('/test', (req, res) => {
     res.send(req.body)
   })
   
   // 调用 app.listen 方法,指定端口号并启动 web 服务器
   app.listen(3000, () => {
     console.log('serve is running')
   })
   

二:JSONP请求

  1. 浏览器端通过 <script> 标签的 src 属性,请求服务器上的数据,同时,服务器返回一个函数的调用。这种请求数据的方式叫做 JSONP
    JSONP的特点是,它不属于真正的ajax请求,因为它并没有使用XMLHTTPRequest这个对象。但它有很大的局限性,它仅支持 GET 请求,不支持 POSTPUTDELETE 等请求

2.实现步骤分析
(1)获取客户端发送过来的回调函数的名字
(2) 得到要通过 JSONP 形式发送给客户端的数据
(3) 根据前两步得到的数据,拼接出一个函数调用的字符串
(4) 把上一步拼接得到的字符串,响应给客户端的 <script> 标签进行解析执行

3.示例代码

   // 导入 express 模块
   const express = require('express')
   
   // 创建 express 的服务器实例
   const app = express()
   
   // 配置解析表单数据的中间件
   app.use(express.urlencoded({ extended: false }))
   
   // 必须在配置 cors 中间件之前,配置 JSONP 的接口
   app.get('/api/jsonp', (req, res) => {
     // 定义 JSONP 接口具体的实现过程
     // 1. 得到函数的名称
     const funcName = req.query.callback
     // 2. 定义要发送到客户端的数据对象
     const data = { name: 'zs', age: 11 }
     // 3. 拼接处一个函数的调用
     const scriptStr = `${funcName}(${JSON.stringify(data)})`
     // 4. 把拼接的字符串,响应给客户端
     res.send(scriptStr)
   })
   
   // 导入中间件
   const cors = require('cors')
   app.use(cors())
 
   // 挂载一个路由
   app.post('/test', (req, res) => {
     res.send(req.body)
   })
   
   // 调用 app.listen 方法,指定端口号并启动 web 服务器
   app.listen(3000, () => {
     console.log('running……')
   })
   

注意

如果项目中已经配置了 CORS 跨域资源共享,为了防止冲突,必须在配置 CORS 中间件之前声明 JSONP 的接口,否则 JSONP 接口会被处理成开启了 CORS 的接口

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

推荐阅读更多精彩内容