虽然前端接触到解决跨域的问题比较少,但是还是需要了解下基本的跨域如何解决的,接下来就主要了解下利用JSONP的方式解决跨域接口的问题
一.什么是跨域以及产生原因
跨域是指a页面想获取b页面资源,但是如果a与b的域名/端口号/协议,其中一项不一致
出现跨域的根本原因:浏览器的同源策略不允许非同源的 URL 之间进行资源的交互
注意:浏览器允许发起跨域请求,但是,跨域请求回来的数据,会被浏览器拦截,无法被页面获取到!
二. 实现跨域数据请求(常见的方式)
- jsonp 需要目标服务器配合一个callback函数。
- window.name+iframe 需要目标服务器响应window.name。
- window.location.hash+iframe 同样需要目标服务器作处理。
- html5的 postMessage+ifrme 这个也是需要目标服务器或者说是目标页面写一个postMessage,主要侧重于前端通讯。
- CORS 需要服务器设置header :Access-Control-Allow-Origin。
- nginx反向代理 这个方法一般很少有人提及,但是他可以不用目标服务器配合,不过需要你搭建一个中转nginx服务器,用于转发请求。
三.JSONP的实现原理
- 原理:浏览器端通过
<script>
标签的src
属性,请求服务器上的数据,同时,服务器返回一个函数的调用,接收跨域接口响应回的数据 - 特点
JSONP
不属于真正的Ajax
请求,因为它没有使用XMLHttpRequest
这个对象JSONP
仅支持GET
请求,不支持POST
、PUT
、DELETE
等请求
四. 代码实现
1.创建JSONP接口 : 实现跨域请求
//js部分:
// 导入express模块
const express = require('express')
// 调用express()
const app = express()
// 给app挂载路由 接收客户端发送的get请求 处理
app.get('/jsonp', (req, res) => {
// 接收客户端发送的过来的查询字符串 得到回调函数的名字
const callback = req.query.callback
// 或者使用解构对象
// const {callback}=req.query
const data = {
uname: 'ls',
age: 20
}
// res.send(`fn(参数)`) 参数为json字符串格式
// 返回客户端一个函数调用的形式 接收跨域接口响应回的数据
res.send(`${callback}(${JSON.stringify(data)})`)
})
app.listen(80, () => {
console.log('http://127.0.0.1');
})
//html部分 测试:
<body>
<script>
function fn(res) {
console.log(res);
}
</script>
<script src="http://127.0.0.1/jsonp?callback=fn"></script>
</body>
2.jQuery
中的JSONP
2.1
jQuery
提供的 $.ajax()
函数,除了可以发起真正的 Ajax
数据请求之外,还能够发起 JSONP
数据请求,例如:
$.ajax({
url: 'http://ajax.frontend.itheima.net:3006/api/jsonp?name=zs&age=20',
// 如果要使用 $.ajax() 发起 JSONP 请求,必须指定 datatype 为 jsonp
dataType: 'jsonp',
success: function(res) {
console.log(res)
}
}
默认情况下,使用
jQuery
发起JSONP
请求,会自动携带一个 callback=jQueryxxx
的参数,jQueryxxx
是随机生成的一个回调函数名称
2.2自定义参数及回调函数名称
在使用 jQuery
发起 JSONP
请求时,如果想要自定义 JSONP
的参数以及回调函数名称,可以通过如下两个参数来指定:
$.ajax({
url: 'http://ajax.frontend.itheima.net:3006/api/jsonp?name=zs&age=20',
dataType: 'jsonp',
// 发送到服务端的参数名称,默认值为 callback
jsonp: 'callback',
// 自定义的回调函数名称,默认值为 jQueryxxx 格式
jsonpCallback: 'abc',
success: function(res) {
console.log(res)
}
})
2.3 jQuery
中JSONP
的实现过程
jQuery
中的 JSONP
,也是通过 <script>
标签的 src
属性实现跨域数据访问的,只不过,jQuery
采用的是动态创建和移除标签的方式,来发起 JSONP
数据请求。
-
在发起
JSONP
请求的时候,动态向<header>
中 append 一个<script>
标签; -
在
JSONP
请求成功以后,动态从<header>
中移除刚才append
进去的<script>
标签;