跨域
跨域问题是我们前端开发中经常会遇到的问题,希望通过这篇博客,小伙伴们就能解决这类问题啦
素材准备以及错误演示
根目录
├── public
│ ├── js
└── axios.js
│ └── index.html # 提前准备好的页面
└── server.js
前端页面
public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<p>
<button id="btn1_get">接口测试1:get请求带参数</button>
</p>
<p>
<button id="btn2_post"> 接口测试2:post-传递普通键值对</button>
</p>
<p>
<button id="btn3_postJSON">接口测试3:post-传递json</button>
</p>
<form id="myform">
<input type="text" name="title">
<input type="file" name="cover">
</form>
<button id="btn4_formdata">接口测试4:post-传递formdata</button>
<script src="./js/axios.js"></script>
<script>
document.getElementById('btn1_get').addEventListener('click', () => {
axios.get('http://localhost:3000/getapi', { params: { a: 1, b: 2 } })
})
var obj = {
"name": "abc",
"address": {
"a": 1,
"b": 2,
"info": "c"
}
}
// axios库发送 普通键值对的参数
document.getElementById('btn2_post').addEventListener('click', () => {
const params = new URLSearchParams();
// 属性名,属性值
params.append('param1', 'value1');
params.append('param2', 'value2');
axios.post('http://localhost:3000/post', params, {
headers: { "content-type": "application/x-www-form-urlencoded" }
})
})
document.getElementById('btn3_postJSON').addEventListener('click', () => {
axios.post('http://localhost:3000/postJSON', obj)
})
document.getElementById('btn4_formdata').addEventListener('click', () => {
console.log(1)
var fd = new FormData(document.getElementById('myform'));
axios.post('http://localhost:3000/publish',
fd
)
})
</script>
</body>
</html>
后端代码
// 1. 引入包
const multer = require('multer')
// 2. 配置
const upload = multer({ dest: 'uploads/' }) // 上传的文件会保存在这个目录下
// uploads表示一个目录名,你也可以设置成其它的
//1.导入模块
const express = require('express')
//2.创建服务器
let app = express()
//静态资源托管
app.use(express.static('public'))
//键值对的中间键
app.use(express.urlencoded())
app.use(express.json())
//接口1 get
app.get('/getapi', (req, res) => {
console.log('收到的参数是', req.query)
res.send({ message: 'ok' })
})
//接口2 post
app.post('/post', (req, res) => {
console.log('收到的参数是', req.body)
res.send({ message: 'ok' })
})
//接口3 postJSON
app.post('/postJSON', (req, res) => {
console.log('收到的参数是', req.body)
res.send({ message: 'ok' })
})
//接口4 上传文件
app.post('/publish', upload.single('cover'), (req, res) => {
console.log('收到的参数是', req.body)
res.send({ message: 'ok' })
})
//3.开启服务器
app.listen(3000, () => {
console.log('success')
})
此时如果用localhost打开的话,接口都正常使用,但是如果我们使用鼠标双击index.html页面然后测试接口的话,系统就会直接报错,就有了跨域问题 错误提示如下 :
如何解决跨域问题
一、CORS
CORS是一个W3C标准,全程是"跨域资源共享"(Cross-origin resource sharing).它允许浏览器想跨院服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制.
CORS需要浏览器和服务器同时支持.目前,所有浏览器都支持该功能.IE浏览器不能低于IE10(ie8通过XDomainRequest能支持CORS)。
手写实现
通过在被请求的路由中设置header头,可以实现跨域
//接口 get
app.get('/getapi', (req, res) => {
//表示允许任何域名来访问
res.setHeader('Access-Control-Allow-Origin','*')
res.send({ message: 'ok' })
})
使用cors
- 它是一个npm包,要单独下载使用npm包cros
npm i cros - 当做express中的中间键,注意代码应该放在顶部
var cors = require('cors')
app.use(cors())