解决跨域的4种方案

解决跨域

跨域:页面地址和页面请求的接口地址中协议、域名、端口号有一样不同,就说明跨域了,此时,请求会报错

发生跨域的场景:前后端分离式开发、调用第三方接口

解决跨域的4种方案:

  1. CORS中间件

    • 全称:Cross-Origin Resource Sharing 跨域资源共享

    • 是由一系列HTTP头部组成的系统,http头部可以阻止或者允许前端跨域请求的响应

    • 最流行的跨域解决方案

    • 同源策略默认阻止跨域获取资源,但CORS可以选择性的允许或阻止跨域获取资源

    • OCRS头部:

      • Access-Control-Allow-Origin 指定请求的资源可以共享给哪些域
      • Access-Control-Allow-Credentials 允许跨域请求的凭证,值为true或false
      • Access-Control-Allow-Headers 在预请求中列出正式请求中可以使用哪些请求头
      • Access-Control-Allow-Methods 指定允许前端跨域请求接口时使用哪些请求方法(get\post…)
      • Access-Control-Expose-Headers 指定可以在客户端浏览器中显示的HTTP头部
      • Access-Control-Max-Age 指定预请求的结果可以缓存多长时间,值为整数,单位秒
      • Access-Control-Resquest-Headers 在预请求中告知服务器正式请求中会使用哪些请求头
      • Access-Control-Request-Method 在预请求中告知服务器正式请求会使用哪些请求方法
      • Origin 指示是谁(协议、域名、端口号)发起跨域请求
    • 设置请求头的方式:

      res.setHeader('Access-Control-Allow-Origin', '*');
      res.setHeader("Access-Control-Allow-Methods", "GET, PUT, OPTIONS, POST");
      

  2. nginx反向代理

    • 将请求发送给代理服务器,静态页面和代理服务器之间是同源的,然后代理服务器项后端服务器发请求,服务器和服务器之间不存在跨域
  3. JSONP

    • 原理:script标签可以跨域请求资源

    • 缺点:只能默认发起get请求

    • 需要了解的知识点:

      • html中script标签的type属性默认为text/javascript,跨域请求的内容会被当成js代码被执行
      • script标签允许跨域请求资源
    • 最简单的jsonp实现:

      • 在客户端中创建一个与服务端名称对应的全局函数
      • 在script标签中的src属性中引用服务端文件调用该函数,就可以获取该函数中的参数
      • 整个过程就是一个函数函数和参数传递过程
      // 客户端 client.html 文件:
      <body>
        <script>
          window.getData = function (data) {
            console.log('data', data) // data {name: 'yangzhiling', age: 99}
          }
        </script>
        <script src="http://127.0.0.1:8001/1_jsonp/server.js"></script>
      </body>
      
      // 服务端 server.js 文件:
      getData({
        name: 'yangzhiling',
        age: 99
      })
      
    • 实际中,服务端和客户端之间的数据传递要使用json格式的数据。jsonp的完整使用过程:

      • 客户端在script标签的src属性中跨域请求资源的url地址中使用查询字符串拼接要请求数据对应的函数
      • 客户端创建一个与请求资源函数对应的函数,该函数获取的参数即我们想要请求的数据
      • 服务端将包含真实数据的的整个函数转化为json格式发送给客户端
      • 客户端得到这个json格式的函数后,执行该函数,获取数据。由于经常使用js函数包裹json数据,所以这个过程被称为json with padding,简称jsonp
    • 自定义jsonp函数:

      • 创建script标签
      • 将请求的url地址和想要请求的函数拼接到script标签的src属性中
      • 每次请求前清空上一次的请求
      <!-- 自定义jsonp函数 -->
      <script>
        function jsonp(url, callback) {
          const cb = '__jp0'
          const script = document.createElement('script')
          script.src = `${url}?callback=${cb}`
          document.body.appendChild(script)
          window[cb] = function (data) {
            clear()
            callback(data)
          }
          function clear() {
            document.body.removeChild(script)
            window[cb] = null
          }
        }
        jsonp('http://127.0.0.1:8002/jsonp', function (data) {
          console.log(data) // {name: 'yangzhiling', age: 99}
        })
      </script>
      
      // 自定义服务器 server.js
      const express = require('express')
      const db = require('./db.json')
      const router = require('./router.js')
      
      const app = express()
      
      app.use(router)
      
      app.listen(8002, () => {
        console.log('express server running at http://127.0.0.1:8002')
      })
      
      // 自定义路由 router.js
      const express = require('express')
      const db = require('./db.json')
      
      const router = express.Router()
      
      router.get('/jsonp', (req, res) => {
        const cb = req.query.callback ?? 'cb'
        res.send(`${cb}(${JSON.stringify(db.messages)})`)
      })
      
      module.exports = router
      
      // 自定义json数据 db.json
      {
        "messages": {
          "name" : "yangzhiling",
          "age" : 99
        }
      }
      
      

  4. postmessage()

    • 跨域通信
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值