一篇文章彻底搞懂跨域问题

1. CORS解决Ajax跨域问题

1.1. CORS概述

CORS全称跨域资源共享,是用于控制浏览器校验 跨域请求的一套规范,添加特定响应头来控制浏览器校验

  • 服务器明确表示拒绝或没有表示,则浏览器校验不通过
  • 服务器明确表示允许跨域请求,则浏览器校验通过

1.2CORS解决简单请求跨域问题

javascript 复制代码
const books = [
    {id: 'abcd',name:''},
]
//  简单请求
app.get('/books',(res,req) =>{
    // 添加响应头,允许这个原开始进行跨域
    res.setHeader('Access-Control-Allow-Origin','http://127.0.0.1:8080')
    res.send(books);
})

1.3简单请求和复杂请求

1.3.1简单请求

  • 只需要记住简单请求就可以,其它均是复杂请求,GET 、HEAD、POST
  • 请求头字段要符合《CORS安全规范》(一般不用管都符合)
  • 请求头的Content-Type的值只能是: text/plain、multipart/form-data、application/x-www-form-urlencoded

1.3.2复杂请求

  • 不是简单请求,就是复杂请求。
  • 复杂请求会自动发送预检请求。(preflight)

关于预检请求

  1. 发送时机:预检请求在实际跨域请求之前发出,是由浏览器自动发起的。

  2. 主要作用:用于向服务器确认是否允许接下来的跨域请求。

  3. 基本流程:先发起OPTIONS请求,如果通过预检,继续发起实际的跨域请求。

  4. 请求头内容:一个OPTIONS预检请求,通常会包含如下请求体:

    Origin/Access-Control-Request-Method/Access-Control-Request-Headers

1.4 CORS解决预检请求的跨域问题

javascript 复制代码
const books = [
    {id: 'abcd',name:''},
]
// 预检请求同意跨域请求通过,并且必须要有回复,(什么不重要)
app.options('/books',(req,res) => {
    res.setHeader('Access-Control-Allow-Origin','http://127.0.0.1:8080')
    res.setHeader('Access-Control-Allow-Methods','GET')
    res.setHeader('Access-Control-Allow-Headers','library')
    //res.setHeader('Access-Control-Max-Age',7200)
    res.send()
})
//  简单请求
app.get('/books',(req,res) =>{
    // 添加响应头,允许这个原开始进行跨域
    res.setHeader('Access-Control-Allow-Origin','http://127.0.0.1:8080')
    res.send(books);
})

1.5借助Cros库

less 复制代码
npm i cros // 封装好了的预检请求中间件
php 复制代码
const express = require('express')
const cors = require('cors')
const app = express()
app.use(cors({
    origin: '', // 允许的源
    methods: ['GET','PUT','POST','DELETE','HEAD','OPTIONS'], // 允许的方法
    allowedHeaders: ['school'], // 允许的自定义头
    exposedHeaders: ['abc'], // 要暴露的响应头
}))

2. JSONP 解决跨域问题

  1. JSONP概述:JSONP是利用了

2.JSONP解决的原理

xml 复制代码
<button onclick="getStudents()">获取学生数据</button>
<script type="text/javascript">
    function test(data){
        console.log(data)
    }
    function getStudents(){
        const script = document.createElement('script')
        // 防止重复创建
        script.onload = () => {
            script.remove()
        }
        script.src = 'http://127.0.0.1:8081/teachers?callback=test'
        document.body.appendChild(script)
    }
</script>
javascript 复制代码
app.get('/books',(req.res) =>{
    const {callback} = req.query;
    res.send(`${callback}(${JSON.stringfy(teachers)})`)
})

3. 自己配置代理服务器

css 复制代码
npm i http-proxy-middleware

4.Nginx 是一种高性能的反向代理服务器,可以用来轻松解决跨域问题

反向代理拿到客户端的请求,将请求转发给其他的服务器,主要的场景是维持服务器集群的负载均衡 ,换句话说,反向代理帮其它的服务器拿到请求,然后选择一个合适的服务器,将请求转交给它。

因此,两者的区别就很明显了,正向代理服务器是帮客户端 做事情,而反向代理服务器是帮其它的服务器做事情。

Nginx 相当于起了一个跳板机,这个跳板机的域名也是client.com,让客户端首先访问 client.com/api,这当然没有跨域,然后 Nginx 服务器作为反向代理,将请求转发给server.com,当响应返回时又将响应给到客户端,这就完成整个跨域请求的过程。

相关推荐
jin12332225 分钟前
基于React Native鸿蒙跨平台地址管理是许多电商、外卖、物流等应用的重要功能模块,实现了地址的添加、编辑、删除和设置默认等功能
javascript·react native·react.js·ecmascript·harmonyos
2501_9209317043 分钟前
React Native鸿蒙跨平台医疗健康类的血压记录,包括收缩压、舒张压、心率、日期、时间、备注和状态
javascript·react native·react.js·ecmascript·harmonyos
落霞的思绪1 小时前
配置React和React-dom为CDN引入
前端·react.js·前端框架
Hacker_Z&Q1 小时前
CSS 笔记2 (属性)
前端·css·笔记
Anastasiozzzz1 小时前
LeetCode Hot100 295. 数据流的中位数 MedianFinder
java·服务器·前端
橙露2 小时前
React Hooks 深度解析:从基础使用到自定义 Hooks 的封装技巧
javascript·react.js·ecmascript
Exquisite.2 小时前
Nginx
服务器·前端·nginx
2501_920931702 小时前
React Native鸿蒙跨平台使用useState管理健康记录和过滤状态,支持多种健康数据类型(血压、体重等)并实现按类型过滤功能
javascript·react native·react.js·ecmascript·harmonyos
打小就很皮...2 小时前
dnd-kit 实现表格拖拽排序
前端·react.js·表格拖拽·dnd-kit
Ulyanov2 小时前
从静态到沉浸:打造惊艳的Web技术发展历程3D时间轴
前端·javascript·html5·gui开发