1. 跨域是什么: ajax地址 和 页面地址 不同源
- 浏览器使用ajax时, 如果请求接口地址和当前打开页面地址不同源, 称为跨域
- ajax地址: 跨域只会出现在ajax请求中, 其他的请求没有跨域
- 页面地址: location.href地址栏
- 不同源: 浏览器同源策略: 协议名、端口号、主机ip都一致
当页面发生跨域, 就会产生一个固定格式的报错 只要是跨域, 就一定会出现下面这种格式的报错, 但这种格式报错原因有很多, 比如基地址错误、服务器内部问题、跨度都有可能出现这种错误 Access to XMLHttpRequest at ‘ajax请求网址’ from origin ‘页面网址’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
2. 同源策略是一种安全策略
- 当使用ajax请求地址时, 与当前页面地址不一致时, 浏览器会认为给不同服务器发送了请求, 可能导致数据泄露, 因此会拒绝接收服务器的数据
- 跨域: 服务器可以收到请求, 也响应了请求, 但响应的数据被浏览器拒收了
- 出于安全考虑, 浏览器不允许页面向不同源的接口请求数据, 因为如果接口和网页不同源, 浏览器认为是2个不同的 服务器, 关于同源策略点击
分析以下有没有跨域:
- 页面地址: http://127.0.0.1:3000
- http://127.0.0.1:3000/list 同源
- http://127.0.0.1:5000 不同源 端口号不一样
- https://127.0.0.1:3000 不同源 协议名不一致
- http://localhost:3000 不同源 ip不一致
3. 如何解决跨域?
1. CORS技术: 后台设置允许跨域的响应头
- 应用场景: 前提是后台是自己的, 更多关于CORS
// 服务器在返回响应报文时, 在响应头中设置一个允许的header
res.setHeader('Access-Control-Allow-Origin', '*')
// 参数: 1.响应头名字 2.响应头值 *为所有网站都可以
2. 代理服务器
- 代理服务器: 用于帮你转发请求的服务器, 相当于中介代理
- 跨域只对浏览器ajax有限制, 对nodejs没有限制
- 使用代理转发请求-axios库: 既可在浏览器使用,也可在服务器使用,它会自动判断当前代码运行环境
- 将数据返回给浏览器 (服务器不能直接给对象, 需转换为json)
let http = require('http')
let axios = require('axios') // 导入axios
let app = http.createServer(async (req, res) => {
// 1. 设置允许跨域响应头
// 参数: 1.响应头名字 2.响应头值 *为所有网站都可以
res.setHeader('Access-Control-Allow-Origin', '*')
res.writeHead(200, {
'Content-Type': 'text/html;charset=utf-8'
})
if (req.url == '/') {
res.end('请求成功')
} else if (req.url == '/a') {
// 2. 使用axios库: 既可在浏览器使用,也可在服务器使用,它会自动判断当前代码运行环境
let res1 = await axios.get('http://c.m.163.com/nc/article/headline/T1348647853363/0-40.html')
console.log(res1)
// 3. 将数据返回给浏览器 (服务器不能直接给对象, 需转换为json)
res.end(JSON.stringify(res1.data))
} else {
res.end('404 not found')
}
})
app.listen('3000', '', () => {
console.log('开启成功')
})
代码语言:javascript复制document.querySelector('.btn1').addEventListener('click', function () {
// 给我们自己nodejs服务器发请求
let xhr = new XMLHttpRequest()
xhr.open('get', 'http://127.0.0.1:3000/')
xhr.send()
xhr.onload = function () {
console.log(xhr.responseText)
}
})
document.querySelector('.btn2').addEventListener('click', function () {
//给别人的网易云服务器发请求
let xhr = new XMLHttpRequest()
// xhr.open('get', 'http://c.m.163.com/nc/article/headline/T1348647853363/0-40.html')
// 使用代理服务器解决跨域
xhr.open('get', 'http://127.0.0.1:3000/a')
xhr.send()
xhr.onload = function () {
console.log(xhr.responseText)
}
})
3. 代理服务器流程
- 页面 给 代理服务器 发请求
- 代理服务器 给 目标服务器 发请求
- 目标服务器 把 数据响应给代理服务器
- 代理服务器 最后把 数据响应给页面