什么是“跨域”及解决跨域有(两种方案)
1.跨域介绍
1.当你的浏览器出现跨域的时候,会有固定格式的报错
Access to XMLHttpRequest at 'http://127.0.0.1:3000/api/getbooks' from origin 'xxx' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
2.跨域是什么?
跨域 : "ajax请求地址" 与 "当前页面地址" "不同源" , 称为跨域 (1)ajax请求 : 跨域只会出现在ajax请求 * ajax地址 : 服务器接口文档地址 (2)当前页面地址 : location.href (3)不同源 : 协议名、ip地址、端口号 只要有任意一个不相同,就是不同源
3.什么是同源
同源 : 协议名、ip地址、端口号 三者一致就叫同源 当前页面地址 : http://127.0.0.1:3000/home/index.html ajax地址1 : https://127.0.0.1:3000/abc (不同源,协议不同) ajax地址2 : http://127.0.0.1:3000/abc (同源, 三码合一) ajax地址3 : http://192.168.48.81:3000/abc (不同源, ip不同) ajax地址4 : http://127.0.0.1:4399/abc (不同源,端口号不同)
4.浏览器为什么要有这种跨域限制?
*浏览器为了保护用户安全, 当用户ajax发送的地址 和 页面地址
不同源,浏览器会认为你向两个服务器发 送了请求,所以就会阻止这种行为。*
解决跨域有两种方案
(1)CORS技术 : 现在主流解决方案, 不需要前端写任何代码
方案:服务器只需要设置一个允许跨域响应头即可
res.setHeader('Access-Control-Allow-Origin', '*')
(2)jsonp技术 : 以前的方案,现在很少使用。 原理和流程复杂,可以提现前端技术含量。
(1)只有ajax请求才会出现跨域, 其他的请求不存在跨域 -->
<a href="http://127.0.0.1:3000/abc">点我发请求</a>
(2)点击按钮发送ajax请求
<button>点我发送ajax请求</button>
(3)jsonp技术解决跨域
1.核心原理 : 利用script标签src属性来发送请求, 因为跨域只对ajax有限制
2.了解script标签src属性做了什么事情
(1)给服务器发送请求
(2)执行服务器响应返回的js代码
3.jsonp完整流程
(1)浏览器 : 声明一个函数,用于接收服务器响应数据
(2)浏览器: 写一个script标签, 路径是jsonp请求地址,添加一个额外参数callback=函数名
(3)服务器: 处理完请求之后, 返回一个函数调用的js代码,格式res.send( '函数名(响应数据)' )
* 函数名需要从参数callback获取
(4)浏览器就会执行script标签响应的js代码
CORS技术解决跨域
const fn = res=>{
console.log(res)
}
</script>
<script src="http://127.0.0.1:3000/aaa?callback=fn"></script>
<script>
//cors按钮
document.querySelector('button').addEventListener('click', function () {
//(1).实例化ajax对象
let xhr = new XMLHttpRequest()
//(2).设置请求方法和地址
//get请求的数据直接添加在url的后面 格式是 url?key=value
xhr.open('get', 'http://127.0.0.1:3000/abc')
//(3).发送请求
xhr.send()
//(4).注册回调函数
xhr.onload = function () {
console.log(xhr.responseText)
}
})
</script>
jsonp技术解决跨域
<script>
/*
1.jsonp整体工作流程(把jsonp封装到按钮点击事件里面)
(1)浏览器: 声明函数接收服务器响应数据
(2)浏览器: 点击按钮给页面添加script,添加额外参数callback=函数名
(3)服务器 : 响应函数调用js代码 res.send('函数名(响应数据)')
(4)浏览器: script标签会执行服务器响应的js
*/
const getBook = res => {
console.log(res)
//一旦响应了jsonp数据之后,就移除script标签
document.querySelector('#jsonp').remove()
}
document.querySelector('button').addEventListener('click', function () {
//(1)声明函数接收服务器响应数据 (需要是全局函数)
//(2)给页面动态添加script
const script = document.createElement('script')
script.src = 'http://127.0.0.1:3000/aaa?callback=getBook'
script.id = 'jsonp'
//一般动态jsonp会添加到head标签
document.body.appendChild(script)
})
</script>
代码演示
//1.导入模块
const express = require('express')
//2.创建服务器
let app = express()
//设置跨域中间件 : 类似于拦截器,会给每一个路由自动设置允许跨域响应头
// //(1)导入模块
// const cors = require('cors')
// //(2)使用模块
// app.use(cors())
//1. cors技术解决跨域
app.get('/abc',(req,res)=>{
//允许跨域响应头
res.setHeader('Access-Control-Allow-Origin', '*')
//设置content-type响应头
//响应数据
res.send('<h1>我是html</h1>')
})
//2. jsonp技术解决跨域
app.get('/aaa',(req,res)=>{
console.log(req.url)
console.log(req.query)
//调用浏览器传递过来的那个函数名
res.send(`${req.query.callback}(["西游记","水浒传"])`)
})
//3.开启服务器
app.listen(3000, () => {
console.log('success')
})
转载自:https://juejin.cn/post/7100403790297661453