话不多说,直接前端代码如下:
jsonp
原理:利用的原理是script标签可以跨域请求资源,将回调函数作为参数拼接在url中。后端收到请求,调用该回调函数,并将数据作为参数返回去,注意设置响应头返回文档类型,应该设置成javascript。
html中首先声明回调处理函数,然后动态创建script标签发送请求信息
<body>
<button id="btn">发送xml请求</button>
<textarea name="" id="data" cols="30" rows="10"></textarea>
<script>
document.querySelector('#btn').addEventListener('click', () => {
window.jsonpCallback = (res) => {
document.querySelector('#data').innerHTML = JSON.stringify(res)
}
let script = document.createElement('script')
script.type = 'text/javascript'
script.src = 'http://localhost:8080/api/jsonp?id=1&cb=jsonpCallback'
document.body.appendChild(script)
})
</script>
<!-- <script src="http://localhost:8080/api/jsonp?id=1&cb=jsonpCallback" type="text/javascript"></script> -->
</body>
服务端需要安装koa或者express框架创建app,根据获得的回调格式使用相同的回调函数返回数据
const Koa = require('koa')
const app = new Koa()
const data = [
{id: 1, title: '张三', age: 17},
{id: 2, title: '李四', age: 18}
]
app.use(async (ctx, next) => {
if(ctx.path === '/api/jsonp') {
const { id, cb } = ctx.query
const info = data.find(item => item.id == id)
ctx.body = `${cb}(${JSON.stringify(info)})`
return
}
})
app.listen(8080, () => console.log('listen 8080 ...'))
cors
原理:目前最常用的一种解决办法,通过设置后端允许跨域实现。
使用XMLHttpRequest创建ajax请求,这里使用axios或者其他的ajax封装库都一样
<body>
<button id="btn">发送xml请求</button>
<textarea name="" id="data" cols="30" rows="10"></textarea>
<script>
document.querySelector('#btn').addEventListener('click', () => {
const XML = new XMLHttpRequest()
XML.open('get', 'http://localhost:8080/api/xml')
XML.send()
XML.onreadystatechange = () => {
if(XML.readyState === 4 && XML.status === 200) {
document.querySelector('#data').innerHTML = XML.response
}
}
XML.onerror = (e) => {
console.error('err:' + e);
}
})
</script>
</body>
设置响应体的头部的两个属性如下即可:'Access-Control-Allow-Origin', '*','Access-Control-Allow-Methods', 'OPTIONS, GET, PUT, POST, DELETE'。(也可使用cors封装库,此处省略)
const Koa = require('koa')
const app = new Koa()
const data = [
{id: 1, title: '张三', age: 17},
{id: 2, title: '李四', age: 18}
]
app.use(async (ctx, next) => {
ctx.set('Access-Control-Allow-Origin', '*');
ctx.set('Access-Control-Allow-Methods', 'OPTIONS, GET, PUT, POST, DELETE');
if(ctx.path === '/api/xml') {
ctx.body = `${JSON.stringify(data)}`
return
}
})
app.listen(8080, () => console.log('listen 8080 ...'))
其他方案
其他方案本人用的比较少,此处不详细代码阐释。
-
node中间件、nginx反向代理
跨域限制的时候浏览器不能跨域访问服务器,node中间件和nginx反向代理,都是让请求发给代理服务器,静态页面面和代理服务器是同源的,然后代理服务器再向后端服务器发请求,服务器和服务器之间不存在同源限制
-
postmessage
H5新增API,通过发送和接收API实现跨域通信。
<body> <script> //这个只是给自己本地发送信息 const msg = { name: '昂三' } window.postMessage(msg, 'http://127.0.0.1:5500') window.addEventListener('message', (e) => { console.log(e.data); console.log(e.origin); console.log(e.source); }) </script> </body>
最后
有疏漏之处,请斧正。。。