什么是同源?
同源是指:协议、地址、端口三者都相同。
比如:
ajax地址: http://127.0.0.1:3000/info
页面地址: http://127.0.0.1:3000/add
以上情况就可以说ajax请求地址与当前页面地址同源
什么是不同源?
协议、地址、端口三者有任意一个或多个不相同就是不同源。
比如:
ajax地址:http://127.0.0.1:3000/info
页面地址:https://127.0.0.1:3000/add // 协议名不一致
页面地址:http://127.123.123.1:3000/add // 地址不一致
页面地址:https://127.0.0.1:4000/add // 端口不一致
以上情况就可以说ajax请求地址与当前页面地址不同源
为什么要有同源策略?
浏览器为了保护电脑的安全,当ajax请求地址与当前网页地址不一致的时候,浏览器会禁止ajax向服务器发送的请求
什么是跨域?
ajax请求地址和当前网页地址不同源即为跨域
跨域固定报错格式:
如何解决跨域问题?
1. CORS技术:
// 导入 express
const express = require('express')
// 创建服务器对象
const app = express()
// 设置端口号
const port = 3000
// 自定义中间件
app.use((request, response, next) => {
// 设置允许跨域的响应头
response.setHeader('Access-Control-Allow-Origin', '*')
// 继续执行后续逻辑
next()
})
// 开启服务器监听
app.listen(port, () => {
console.log('服务器启动成功,端口为:', port)
})
2. JSONP技术:
-
JSONP原理:
跨域只限于发送ajax请求,script标签的src属性发送的请求没有跨域的限制。 -
JSONP的工作流程:
原生中:
(1)在script标签的src属性发送请求
(2)在url后面添加一个callback的参数,参数值为函数名
(3)服务器响应,调用函数
jQuery中:
(1)在head标签中动态生成script标签,使用src属性来发送请求
(2)服务器响应回来之后,动态移出script标签 -
前端部分原生写法
<script>
function success(backData) {
console.log(backData)
}
</script>
<script src="http://127.0.0.1:3000/jsonp?callback=success"></script>
- 前端部分jQuery写法
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<button>jsonp</button>
<script>
$('button').click(function () {
$.ajax({
// 请求地址
url: 'http://127.0.0.1:3000/jsonp',
// 设置jsonp请求
dataType: 'jsonp',
success (backData) {
console.log('backData:', backData)
}
})
})
</script>
- 后端部分
// 导入express
const express = require('express')
// 创建服务器对象
const app = express()
// 设置端口
const port = 3000
// 注册路由
app.get('/jsonp', (req, res) => {
// 获取get请求的参数
const { callback } = req.query
// 返回数据
res.send(callback + '({name:"张三"})')
})
// 开启服务器监听
app.listen(port, () => {
console.log('服务器启动成功,端口为:', port)
})
3. Vue中设置跨域代理
// 脚手架设置跨域代理
//vue-cli3.0 里面的 vue.config.js做配置
module.exports = {
devServer: {
proxy: {
'/public': {
//这里最好有一个 /
target: 'http://127.0.0.1/xxx/public', // 后台接口域名
secure: false, // 如果是https接口,需要配置这个参数
changeOrigin: true, //是否跨域
pathRewrite: {
'/public': ''
}
}
}
}
}