我的报错情况是 后端接口是3000 前端本地接口是8080,最后出现跨域
1.什么是跨域?
首先跨域是一种安全机制,是在开发上线前考虑到的安全问题并且需要采取合适的手段去避免这个问题带来的程序错误,接口跨域可以后端处理,也可以前端处理,一般情况下后端会处理跨域的问题,但是为了避免拿到的接口没有解决,我们也可以通过前端来处理跨域这个需求。
2.为什么出现跨域问题:
浏览器不能执行其他网站的脚本,是由浏览器同源策略限制的一类请求场景,从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域。
同源策略是指"协议+ 域名+端口“三者相同,即便两个不同的域名指向同一个ip地址,也非同源,违背同源策略就是跨域。
3.如果不解决跨域会出现什么问题?
首先接口请求不成功
同源策略它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。
4.通过几个案例查看是否跨域了
案例一:是没有跨域问题
浏览器地址: http://localhost:8080/query2.
Ajax请求地址: http://localhost:8080/select
案例二:(跨域了,端口号不一样)
1.浏览器地址: http://localhost:8080/query
2.Ajax请求地址: http://localhost:8081/select
案例三:(跨域了 协议不一样)
1.浏览器地址: http://localhost:8080/query
2.Ajax请求地址: https://localhost:8080/select
案例四:(跨域了 域名不一样)
1.浏览器地址: http://www.baidu.com/query
2.Ajax请求地址: http://163.177.151.109/select
案例五:(没有跨域:: 默认端口号可以省略 https443)
1.浏览器地址 : http://192.168.1.3:80/query
2.Ajax请求地址: http://192.168.1.3/select
案例6:(没有跨域:: 默认端口号可以省略: https443)
1.浏览器地址: https://192.168.1.3/query
2.Ajax请求地址: https://192.168.1.3:443/select
jsonp解决跨域
1.JSONP解决同源限制问题
原理:利用script标签的src属性可以跨域加载资源的特性,通过动态创建script标签来实现跨域请求。
跨源网络访问的三种方式:跨域写操作,跨域资源嵌入,跨域读操作
前端页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- 静态请求 -->
<!-- <script src="http://127.0.0.1:30/api/getData?cb=callback"></script> -->
<script>
// 动态创建script标签
const script = document.createElement('script')
// 设置src属性
script.src = 'http://127.0.0.1:3000/api/getData?cb=callback'
// 接收后端的回调函数
function callback(res) {
console.log(res,'res');
}
// 将script挂载到页面上
document.getElementsByTagName('body')[0].appendChild(script)
</script>
</body>
</html>
node.js页面 (改完之后需要重启一下)
// 引入express
const express = require('express')
// 创建实例
const app = express()
// 创建监听端口
const port = 3000
// 定义接口
// app.get('/api/getData',(req,res) =>{
// // 返回的结果
// res.send({
// code:10000,
// data:{
// msg:'hellow '
// }
// })
// })
// 动态定义接口
app.get('/api/getData',(req,res) =>{
// 获取前端参数
const { cb } = req.query
res.send(`${cb} (${JSON.stringify({
code:10000,
data:{
msg:'哈哈'
}
})})`)
})
// 监听当前的端口
app.listen(port,() =>{
console.log(`server start! port:${port}`);
})
测试
cores解决跨域问题
原理:需要服务器实现CORS接口,在服务器端设置响应头,允许指定的域名访问资源。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>跨域问题</title>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.5.0/axios.min.js"></script>
<script>
axios({
methods:'get',
url:'http://localhost:3000/api/getData'
})
</script>
</body>
</html>
// 引入express
const express = require('express')
// 创建实例
const app = express()
// 创建监听端口
const port = 3000
// '*' 匹配所有任意的路径 req:请求体,res:响应体,next:下一步
app.all('*',(req,res,next)=>{
res.header('Access-Control-Allow-Origin', '*') //允许所有的请求源
res.header('Access-Control-Allow-Headers', '*') //允许所有的请求源 X-Token
res.header('Access-Control-Allow-Methods', '*') //允许所有的请求源 get post put delete
next()
})
// 定义接口
app.get('/api/getData',(req,res) =>{
// 返回的结果
res.send({
code:10000,
data:{
msg:'hellow '
}
})
})
// JSONP动态定义接口
// app.get('/api/getData',(req,res) =>{
// // 获取前端参数
// const { cb } = req.query
// res.send(`${cb} (${JSON.stringify({
// code:10000,
// data:{
// msg:'哈哈'
// }
// })})`)
// })
// 监听当前的端口
app.listen(port,() =>{
console.log(`server start! port:${port}`);
})
代理服务器
原理:在同源策略下,通过在同一域名下设置代理服务器,将跨域请求转发到目标服务器上。
配置代理服务器(仅限于解决本地跨域;项目上线或者打包,要不通过后端解决,要不前端通过nginx反向代理)