跨域
jsonp
-
前端:新建script标签 通过src发送请求 返回函数调用
代码:
1234
我是新增的
我也是新增的
1234---------------------
function jsonp(obj) {参数
obj.type = obj.type || ‘get’;
obj.url = obj.url || ‘’;
let data = { …obj.data };把对象转换成字符串的形式
var arr = [];
for (var k in data) {
arr.push(${k}=${data[k]}
)
}
obj.url =${obj.url}?${arr.join('&')}
;动态创建script标签
var script = document.createElement(‘script’);
script.src = obj.url;
document.body.appendChild(script)
window[data.cb] = function (data) {window[data.cb]
是全局的 目的是把cb里的参数当做函数名,后台返回的show() 去调用 因为cb里的参数不固定,所以以data.cb的形式 相当于function show(){}
obj.success(data)
里的success会自动去调用jsonp里的success return obj.success(data)
}
}
jsonp({
url: ‘http://localhost:3000/say’,
data: {
wd: ‘zs’,
cb: ‘show’
},
success: function (data) {
console.log(data)
}
}) -
后端:
返回函数名调用的形式 数据通过实参传递
代码:
let express = require(‘express’);
let app = express();
app.get(‘/say’, function (req, res) {
let { wd, cb } = req.query;
// console.log(wd)
// res.send(‘ok’)
res.end(${cb}(123)
)
})
app.listen(3000, () => {
console.log(‘启动成功’)
})
cors
- cors 是后端做的操作, 需要为头做一些处理,告诉浏览器一些相关信息。
-
1.告诉浏览器哪个源可以访问我
res.setHeader(‘Access-Control-Allow-Origin’, origin) -
2.告诉浏览器允许携带哪个头可以访问我
res.setHeader(‘Access-Control-Allow-Headers’, ‘name’) -
3.允许哪个请求方法访问我。 浏览器默认支持get post方法
put 方法两次
第一次:试探 询问 options
第二次:发送ajax请求
res.setHeader(‘Access-Control-Allow-Methods’, ‘PUT’); -
4.是否允许携带cookie
res.setHeader(‘Access-Control-Allow-Credentials’, true);
postmessage
实现步骤:
- 首先通过iframe标签向端口4000的b页面发送请求 但是无法传送数据 因为跨域
- 然后获取iframe标签 利用
contentWindow.postMessage
向子页面b发送内容 postMessage里面有两个参数 第一个是发送的内容 第二个是规定向哪个页面发送内容- 接着子页面b通过
window.onmessage
接收到a发送的内容- 再接着通过
e.source.postMessage
向a页面发送内容响应内容- 最后a页面通过
window.onmessage
j接收到内容 存储在e.data
a页面
<body>
<iframe src="http://localhost:4000/b.html" onload="load()" id="box"></iframe>
<!-- <iframe src="http://localhost:4000/b.html" onload="load()" id="frames"></iframe> -->
</body>
<script>
function load() {
let frams = document.querySelector('#box')
frams.contentWindow.postMessage('我爱你', 'http://localhost:4000/b.html');
window.onmessage = function (e) {
console.log(e.data);
}
}
b页面:
window.onmessage = function (e) {
console.log(e);
e.source.postMessage('我不爱你', e.origin)
}
name
实现步骤:
- a页面通过iframe引入子页面c发送请求 页面可以过来但是c页面里的内容不能引入过来,因为端口号不同,所以无法请求
- 在端口4000的c页面上挂载
window.name
- 接下来就是a页面要拿到c页面的
window.name
里的内容
- 获取iframe
var frame = document.querySelector('#frames')
- 直接通过
frame.contentWindow
会出现跨域的问题- 然后让a页面指向一个同域的b页面
frame.src = 'http://localhost:3000/b.html'
- 通过
frame.contentWindow
拿到b页面里的name- 因为是c页面和b页面的window是共享的 所以b可以拿到c的name
- 然后a就可以通过同域的b页面拿到c里面的name
<body>
<!-- <iframe src="http://localhost:4000/c.html" onload="load()" id="frames"></iframe> -->
<iframe src="http://localhost:4000/c.html" onload="load()" id="frames" frameborder="0"></iframe>
</body>
<script>
var first = true
function load() {
var frame = document.querySelector('#frames')
if (first) {
frame.src = 'http://localhost:3000/b.html'
first = false
} else {
console.log(frame.contentWindow.name);
}
}
c页面
<script>
window.name = '我爱你啊'
</script>
hash
hash:是地址栏#号后面的内容 称为hash
- a页面通过iframe向c页面发送请求加上#后面的hash内容
- c页面收到后 a页面接收到不因为跨域
- 然后c页面又向b页面发送请求
iframe.src = 'http://127.0.0.1:3000/b.html#idontloveyou';
- b页面与a页面同域 b页面通过
window.parent.parent.location.hash
找到父级的a页面- a页面通过
window.onhashchange
(只要hash发生变化就会触发这个事件)- 最后a就可以通过
location.hash
把hash内容打印出来
a页面
<body>
<iframe src="http://localhost:4000/c.html#iloveyou" frameborder="0"></iframe>
</body>
<script>
window.onhashchange = function () {
console.log(location.hash)
}
</script>
c页面:
// var iframe = document.createElement('iframe');
// iframe.src = 'http://localhost:3000/b.html#idontloveyou';
// document.body.appendChild(iframe)
b页面:
window.parent.parent.location.hash = location.hash