node.js面试点-跨域和同源

300 阅读5分钟

1.跨域

1.1-跨域固定报错格式

只要是出现跨域问题,浏览器就会出现一个固定格式(没有之一)的报错信息

Access to XMLHttpRequest at '服务器url地址' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

snipaste20220522_084043.jpg 注意 : 跨域一定是这个问题,但出现这个问题不一定是跨域

1.2-什么是跨域?

  • 浏览器使用 ajax,如果请求了的**接口地址** 和 当前**打开的页面** 地址 不同源 称之为跨域

    • (1)ajax : 浏览器只有使用ajax发送请求才会出现跨域。 href属性与src属性不会出现跨域
    • (2) 接口地址 : ajax请求的url
    • (3)打开的页面:当前页面的window.location.href
    • (4)不同源 : 浏览器使用ajax,向不同源的接口发送请求,称之为 跨域访问

1.3-什么是同源?

  • MDN官方文档传送门:developer.mozilla.org/zh-CN/docs/…

  • 同源定义 : 两个url地址的 协议主机端口 均一致 (&&)

    • 协议:http , https , file
    • 主机 : 域名或者ip地址 (127.0.0.1)
    • 端口 :3000, 4399
  • 不同源定义: 两个url地址,协议 主机 端口任何一个不一致 (||)

    • http:127.0.0.1:3000/abc
    • http:127.0.0.1:3000/efg
    • https:127.0.0.1:3000/efg
    • http:127.0.0.1:3000/hero/add
    • http:127.0.0.1:4399/hero/add
    • http:127.0.0.1:4399/hero/all

snipaste20220522_084347.jpg

1.4-为什么要有同源与不同源?

  • 出于安全考虑,浏览器不允许,页面向不同源的接口请求数据,因为如果 接口 和 网页不同源,浏览器认为是2个不同的 服务器,

  • 不同的服务器中内容是不可控的,不允许访问了

  • 总结说人话: 浏览器为了保护你的电脑安全

  • 举个栗子: 你去肯德基店里点餐,店员只允许你点肯德基的产品(炸鸡,可乐,上校鸡块),如果此时你在肯德基店里面点麦当劳的产品,浏览器会认为你是坏人,就会让保安把你赶出去

1.5-跨域解决方案介绍

  • 跨域是前端工作中不可避免的问题:我们经常会出现请求不同源接口的情况,为了能够获取数据,解决跨域的问题方案也有很多,但是常用的就两种

  • 第一种 : CORS

  • 目前的主流方案,也是最简单的方案

  • 第二种:JSONP

    • 曾经的跨域杀手,专治各种跨域问题。现在慢慢的淡出历史舞台
    • PS:面试官特别喜欢问这个,因为这个有一定的技术难度,也能体现一个人的实际开发经验

1.6-示例

前端

<!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>
</head>

<body>
    <a href="http://127.0.0.1:3000/abc">点我发请求</a>
    <br>
    <button>点我发请求</button>

    <script>
        document.querySelector('button').addEventListener('click', function () {
            //(1).实例化ajax对象
            let xhr = new XMLHttpRequest()
            //(2).设置请求方法和地址
            //get请求的数据直接添加在url的后面 格式是 url?key=value
            xhr.open('get', 'http://127.0.0.1:3000/abc')
            //(3).发送请求
            xhr.send()
            //(4).注册回调函数
            xhr.onload = function () {
                console.log(xhr.responseText)
            }
        })
    </script>
</body>

</html>

服务器

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

//2.创建服务器
/* express() 相当于http模块的http.createServer() */
const app = express()


//3.接收客户端请求

app.get('/abc',(req,res)=>{
    //响应客户端数据
    res.send({
        status:200,
        msg:'请求成功',
        data:{name:'张三',age:20}
    })
})



//4.开启服务器
app.listen(3000,()=>{
    console.log('服务器启动成功')
})

2.跨域解决方案

2.1-跨域解决方案一: CORS

2.1.1-CORS工作原理介绍

  • CORS :全称cross origin resource share (资源共享)

  • 工作原理: 服务器 在返回响应报文的时候,在响应头中 设置一个允许的header

    • res.setHeader('Access-Control-Allow-Origin', '*');

snipaste20220522_085109.jpg

snipaste20220522_085117.jpg

2-express使用中间件cors : 给所有的res添加默认请求头Access-Control-Allow-Origin

  • express有一个自带的中间件cors,它的作用是自动给每一个res设置默认请求头

    • 这样就不用我们自己每一个接口都要设置一次了
  • www.npmjs.com/package/cor…

  • 用法介绍

snipaste20220522_085131.jpg

  • cors中间件是最简单的中间,底层原理如下
app.use((req, res, next) => {//任何请求都会进入这个use中间件
  res.setHeader('Access-Control-Allow-Origin', '*')//设置响应头
  next()//执行下一个中间件
})

2.2-跨域解决方案二:原生jsonp

  • 了解jsonp原理,首先一定要明白script标签的src属性做了什么事情

    • (1)scr属性会给服务器发送请求, 请求一个js文件

    • (2)浏览器会解析执行这个js文件里面的代码

      • 如果浏览器直接返回js代码,浏览器会立即执行
  • 1.JSONP的核心原理:如果script标签的src属性的请求,服务器返回的是一个函数调用。则浏览器会执行这个函数

    • 这是浏览器script标签的一个的漏洞(历史遗留问题)

snipaste20220522_085401.jpg

snipaste20220522_085409.jpg

  • 2.实际开发中JSONP的工作流程

    • (1)设置script标签的src属性,向一个不同源的接口发送一个get请求

      • JSONP只支持get请求,不支持post
    • (2)src属性发送请求时,在参数中额外携带一个callback的参数,参数值是一个在页面中预先定于好的函数名

      • callback : 这是发明jsonp技术的人提出的一个君子之约,只要是jsonp前端程序员都统一将参数名定义为callback

        • PS:别的参数也行,只要和服务器协商好
      • callback属性值:预先定义的函数名,这个函数必须要在script标签之前定义

    • (3)服务器接收到请求之后,获取callback的参数值

    • (4)服务器将要响应的数据拼接成 函数调用格式,通过传参的方式将响应数据返回给浏览器

snipaste20220522_085418.jpg

snipaste20220522_085429.jpg

  • 3.JSONP与CORS区别

    • CORS:

      • 服务器返回响应头,前端无需任何处理
      • 简单快捷,支持所有请求方式
    • JSONP

      • 浏览器:自定义响应回调函数,使用script标签的src请求

        • 利用浏览器的src属性没有跨域这一限制特点
      • 服务器:接收callback参数,返回函数调用

      • 处理复杂,并且只支持get请求

        • 原因:get请求参数直接在url后面拼接,而post请求参数是放在请求体中