CORS和JSONP的区别,如何解决跨域问题?

Posted SunFlower914

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CORS和JSONP的区别,如何解决跨域问题?相关的知识,希望对你有一定的参考价值。

在我们了解JSONP CORS 之前我们先明确一下:

我们为什么要使用cors和jsonp呢?

实际上,cors和jsonp都是用于解决跨域问题,当两个页面的协议、域名、端口号中有一个不一致时就存在了跨域,一旦出现跨域,浏览器发送跨域请求后,请求回来的数据都会被浏览器所拦截,准备一张图给大家看看:

 

核心点:如何实现跨域数据请求?(⭐⭐⭐⭐⭐)

现下实现跨域数据请求,最主要的两种解决方案分别是 JSONP CORS

JSONP 出现的早,兼容性好(兼容低版本 IE )。是前端程序员为了解决跨域问题,被迫想出来的一种 临时解决方案,最主要的缺点 是只支持 GET 请求,不支持 POST 请求。
CORS 出现的较晚,它是 W3C 标准,属于跨域 Ajax 请求的根本解决方案。支持 GET POST 请 求。缺点 是不兼容某些低版本的浏览器。

什么是JSONP(⭐⭐⭐)

JSONP (JSON with Padding) 是 JSON 的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。

JSONP的实现原理(⭐⭐⭐) 

  1. 概念:浏览器端通过 <script> 标签的 src 属性,请求服务器上的数据,同时,服务器返回一个函数的调用。这种请求数据的方式叫做 JSONP

  2. 特点: 

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

    JSONP 仅支持 GET 请求,不支持 POSTPUTDELETE 等请求

什么是CORS(⭐⭐⭐⭐⭐)

  1. CORS (跨域资源共享) 由一系列 HTTP 响应头组成,这些 HTTP 响应头决定浏览器 是否阻止前端 JS 代码跨域获取资源

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

 

 

下面分别向大家演示通过CORS和JSONP实现跨域的案例:

一、通过CORS中间件解决跨域问题 :

index.html文件代码演示:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="jquery.min.js"></script>
</head>

<body>
    <button class="get">get请求</button>
    <button class="post">post请求</button>
    <script>
        $('.get').on('click', function() {
            $.ajax({
                method: 'get',
                url: 'http://127.0.0.1/api/get?name=hua&age=18',
                success: function(res) {
                    console.log(res);
                }
            })
        })
        $('.post').on('click', function() {
            $.ajax({
                method: 'post',
                url: 'http://127.0.0.1/api/post',
                data: {
                    name: 'lajitong',
                    age: '111'
                },
                success: function(res) {
                    console.log(res);
                }
            })
        })
    </script>
</body>

</html>

此时会出现跨域问题,我们需要使用 cors 中间件解决跨域问题

  1. cors 是 Express 的一个第三方中间件。通过安装和配置 cors 中间件,可以很方便地解决跨域问题

  2. 使用步骤

    • 安装中间件: npm install cors

    • 导入中间件: const cors = require('cors')

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

  3. express接口案例代码

// 导入 express 模块
const express = require('express')

// 创建 express 的服务器实例
const app = express()

// 导入中间件
const cors = require('cors')
// 配置中间件
app.use(cors())

// 配置解析表单数据的中间件
app.use(express.urlencoded({ extended: false }))

// 导入路由模块(被单独分离后导入)
const router = require('./apiRouter')
// 把路由模块,注册到 app 上
app.use('/api', router)

// 调用 app.listen 方法,指定端口号并启动 web 服务器
app.listen(80, () => {
  console.log('http://127.0.0.1')
})

apiRouter路由文件代码:

const express = require('express');
const router = express.Router();

router.get('/get', (req, res) => {
    const query = req.query;
    res.send({
        status: 0,
        msg: 'get请求成功',
        data: query
    })
})
router.post('/post', (req, res) => {
    // const body = req.body;  //获取客户端请求的数据
    res.send({
        status: 0,
        msg: 'post请求成功',
        data: req.body
    })
})
module.exports = router;

在终端中运行express接口代码后打开index.html文件并点击get及post按钮得到请求结果:

 二、通过JSONP中间件解决跨域问题 :

创建 JSONP 接口的注意事项

  1. 如果项目中已经配置了 CORS 跨域资源共享,为了防止冲突,必须在配置 CORS 中间件之前声明 JSONP 的接口

    否则 JSONP 接口会被处理成开启了 CORS 的接口

  2. 实现步骤:

        (1)获取客户端发送过来的回调函数的名字

        (2)得到要通过 JSONP 形式发送给客户端的数据

        (3)根据前两步得到的数据,拼接出一个函数调用的字符串

        (4)把上一步拼接得到的字符串,响应给客户端的 <script> 标签进行解析执行

案例代码如下:

//导入express模块
const express = require('express');
//创建express服务器实例
const app = express();
//挂载路由
app.get('/jsonp', (req, res) => {
    // 通过解构req.query客户端通过查询字符串的形式发送到客户端的参数fn
    const { callback } = req.query
    //在服务器端定义一个obj对象
    const obj = {
        uname: 'zjj',
        age: '18'
    }
    //obj对象转为res.send可处理的字符串形式后从服务器端相应回调函数至客户端
    res.send(`${callback}(${JSON.stringify(obj)})`)
})
app.listen(80, () => {
    console.log('http://127.0.0.1');
})

创建jsonp.html客户端来接收服务器端响应过来的回调函数,代码如下:

url中callback=fn为客户端发送请求携带的参数 既服务器端中的req.query.callback

<script>
    function fn(res) {
        console.log(res);
    }
</script>
<script src="http://127.0.0.1/jsonp?callback=fn"></script>

以上是关于CORS和JSONP的区别,如何解决跨域问题?的主要内容,如果未能解决你的问题,请参考以下文章

跨域的问题(jsonp和cors)

跨域问题解决方案

vue 如何实现跨域

jsonp-反向代理-CORS解决JS跨域问题的个人总结

AJAX学习笔记2:XHR实现跨域资源共享(CORS)以及和JSONP的对比

使用 JSONP 或 CORS 的跨域 JavaScript 调用