跨域

65 阅读3分钟

什么是跨域(面试题)

  • 请求如果触发了 同源策略 的话,会出现跨域的错误
  • 什么是同源策略
    • 是浏览器的一种保护机制,
      • 请求的时候 域名/协议/端口号 有一个不一样
      • 那么就会触发同源策略,其实就是浏览器认为你这个访问或者请求,不安全
      • 然后给你拦截了
      • 注意:请求此时是成功的! 只不过被浏览器拦截了
  • 如何解决
      1. jsonp
      • 很早之前的解决方案,需要前后端配合
      1. cors
      • 是一种前端最喜欢的解决方案
      1. proxy
      • 不要和ES6的数据代理联想到一起,只是重名

1. jsonp

需要文件:

  1. 新建server-api文件夹,在其下边新建一个index.js文件
    • 代码如下:
        const express = require("express");
        const server = express();
        server.get('/a', (req, res) => {
            // res.send('console.log(123456789)')
            // console.log(req.query)
            const {callback} = req.query
            res.send(`${callback}({code:1,msg:'请求成功'})`)
        })
    
        server.get("/list", (req, res) => {
            console.log('如果我执行了,一定说明有人请求我,并且一定会执行下边的res.send()')
            res.send({
                code: 1,
                msg: "请求成功",
            });
        });
        server.post("/info", (req, res) => {
            res.send({
                code: 1,
                msg: "请求成功",
            });
        });
    
        server.listen("8081", () => console.log("接口服务器开启成功"));
    
  2. 新建server-static文件夹下index.js文件:
    • 代码如下:
        const express = require("express");
        const server = express();
        server.use("/static", express.static("./client"));
        server.listen("8080", () => console.log("静态资源服务器开启成功"));
    
  3. 新建server-static文件夹下引入之前(express笔记中)的client文件夹
    • 在client文件夹下js文件夹内新建index2.css文件
      • 代码如下:
            console.log('123')
        
    • 修改client文件夹下view文件夹内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>
                <!-- <link rel="stylesheet" href="../css/index.css"> -->
                <link rel="stylesheet" href="/static/css/index.css">
            </head>
            <body>
                <h1>我是前端写的静态页面</h1>
                <h1>但我是由服务端帮我放到服务器上</h1>
                <!-- <script src="../js/index.js"></script> -->
                <!-- 
                    一般文件分为两部分
                            1. 文件名: 让你能够区分出文件的差异
                            2. 文件后缀: 给原本能够识别这个文件的软件 看的
                 -->
                 <!-- src属性,取到8081这个服务器内的/a这个接口,拿到数据后执行一遍
                    注意:必须是get方式
                -->
                <script>
                    function fn(res) {
                        console.log('我是这个函数内部的代码,我的文件内没调用',res)
                    }
                </script>
                 <script src="http://localhost:8081/a?callback=fn"></script>
                <!-- <script src="/static/js/index2.css"></script> -->
                <!-- 
                    22行能够正常引入
                    因为src属性并不看你引入的是否是一个JS文件,他只会把这个地址的内容
                    请求过来,然后执行一遍
        
        
                    假设: 一个后端地址内的代码是一串JS代码如果我们通过src属性去访问
                            那么会得到什么呢
        
                -->
            </body>
        
            </html>
        

注意:

  • 开启server-api文件夹下的index.js文件的终端,输入nodemon ./index.js命令,启动后端终端
  • 开启server-static文件夹下的index.js文件的终端,输入nodemon ./index.js命令,启动前端终端
  • 运行结果: image.png

2. cors

  • 前端向服务端发送请求,因为触发同源策略,浏览器认为不安全,所以拦截
  • CORS 的想法:
    • 前端向服务端发送请求,服务端返回内容的时候,告诉浏览器,这是一个安全请求,别拦截了
    • cors的书写有点多不好背,所以给大家推荐一个 第三方包cors
      • 下载 npm i cors
      • 导入 const cors = require('cors')
      • 按需使用 server.use(cors())
      • 即可完成cors
  • 打开server-static文件夹下的index.js文件的终端,输入npm i cors命令下载包

server-api文件夹下的index.js文件导入cors包

  • 代码如下:
    const express = require("express");
    const cors = require('cors');
    const server = express();
    server.use(cors());
    server.get("/list", (req, res) => {
        // 2. 返回给前端数据
        res.send({
            code: 1,
            msg: "请求成功",
        });
    });
    server.post("/info", (req, res) => {
        res.send({
            code: 1,
            msg: "请求成功",
        });
    });
    server.listen("8081", () => console.log("接口服务器开启成功"));

注意:

  • 开启server-api文件夹下的index.js文件的终端,输入nodemon ./index.js命令,启动后端终端
  • 开启server-static文件夹下的index.js文件的终端,输入nodemon ./index.js命令,启动前端终端
  • 运行结果: image.png

3. proxy

  • node 中需要axios 帮助我们发送请求,第三方包的流程: 下载 导入 按照文档使用
  • 安装命令: npm i axios

修改client文件夹下js文件夹下的index.js文件

  • 代码如下:
    // 前端的代码, 发送一个请求
    function myAjax1() {
        const xhr = new XMLHttpRequest();
        xhr.open("GET", "/list");
        xhr.onload = function () {
            console.log(JSON.parse(xhr.responseText));
        };
        xhr.send();
    }
    myAjax1();

    function myAjax2() {
        const xhr = new XMLHttpRequest();
        xhr.open("POST", "/info");
        xhr.onload = function () {
            console.log(JSON.parse(xhr.responseText));
        };
        xhr.send();
    }
    myAjax2();
  • 打开server-static文件夹下的index.js文件的终端,输入npm i axios命令下载包

修改server-static文件夹下的index.js文件

  • 代码如下:
    const express = require("express");
    const axios = require('axios')
    const server = express();
    server.use("/static", express.static("./client"));
    server.get('/list', (req, res) => {
      axios({
        method: 'GET',
        url: 'http://localhost:8081/list',

      }).then(result => {
        res.send(result.data)
      })
    })
    server.post('/info', (req, res) => {
      axios({
        method: 'POST',
        url: 'http://localhost:8081/info',
      }).then(result => {
        // console.log(result.data)
        res.send(result.data)
      })
    })
    server.listen("8080", () => console.log("静态资源服务器开启成功"));

注意:

  • 开启server-api文件夹下的index.js文件的终端,输入nodemon ./index.js命令,启动后端终端

  • 开启server-static文件夹下的index.js文件的终端,输入nodemon ./index.js命令,启动前端终端

  • 运行结果:

    image.png