跨域
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.是否允许携带cookieres.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.onmessagej接收到内容 存储在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
\