本文共--字 阅读约--分钟 | 浏览: -- Last Updated: 2021-12-15
代理模式(Proxy):由于一个对象不能直接引用另一个对象,所以需要通过代理对象在这两个对象之间起到中介的作用。
在前端应用中,常常使用代理用来解决跨域问题。
代理对象有很多,比如img标签通过src属性向其他域下的服务器发送请求,不过这类请求只能是get,并且是单向的。
var Count = (function () {
var img = new Image();
return function (params) {
var str = "http://www.count.com/a.gif?";
for (var key in params) {
str += key + "=" + params[key]
}
img.src = str;
}
})();
Count({num: 10})
第二个代理对象形式是通过script标签。与image标签一样,通过src属性想其他域下的服务器发送请求,但是script返回的脚本文件是js文件,是可以被执行的,我们通过传递出去指定的callback函数名,使得返回的脚本,来执行该callback并传入相关的数据。
<script src="http://localhost/test/josnp.php?callback=jsonpCb"></script>
<script>
window.jsonpCb = function (data) {
console.log(data);
}
</script>
对应的服务器则只需要根据参数返回一段能被执行的脚本即可。取得对应的callback函数名,然后返回 jsonpCb("服务器传给你的数据")
这样一段脚本文件即可,这段脚本文件被加载执行,对应的回调函数就会被调用。
关于代理模板的解决思路是这样的,既然不同域之间相互调用对方的页面是有限制的,那么自己域中的两个页面相互之间的调用是可以的,即代理页面B访问被代理页面A是可以的,要实现这种方式我们只需要在被访问的域中,请求返回的Header重定向到代理页面,并在代理页面访问被代理页面即可。
即X域中的A页面发送请求到Y域,Y域接收到请求后处理重新向到X域中B页面,并通过URL携带数据,X域中的B页面被访问时会解析URL获取数据然后调用A页面的回调函数。
A页面 => http://localhost:8000/page/index.html
<script>
function cb(data) {
console.log("成功接受数据", data)
}
</script>
<!-- action: 规定当提交表单时向何处发送表单数据。 -->
<!-- target: 规定在何处打开 action URL。 (framename/_blank/_self/_parent/_top) -->
<form action="http://localhost:3000/test/proxy" method="post" target="proxyIframe" >
<input type="text" name="callback" value="cb">
<input type="text" name="proxy" value="http://localhost:8000/page/proxy.html">
<input type="submit" value="提交">
</form>
<iframe name="proxyIframe" id="proxyIframe"></iframe>
B页面 => http://localhost:8000/page/proxy.html
<script>
window.onload = function () {
if (top == self ) return;
var arr = location.search.substr(1).split('&');
var fn, args = {};
for (var i = 0, len = arr.length; i < len; i++) {
const [key, value] = arr[i].split('=');
if (key === 'callback') {
fn = value;
} else {
args[key] = value;
}
}
try {
eval(`top.${fn}(${JSON.stringify(args)})`)
} catch (error) {
// handle error
}
}
</script>
Y域对应的服务端 => 提供服务的接口http://localhost/test/proxy
后台服务server.js相关代码如下:
// server.js
const Koa = require('koa');
const route = require('koa-route');
const bodyParser = require('koa-bodyparser');
const app = new Koa();
app.use(bodyParser())
const redirect_test = ctx => {
const post_params = ctx.request.body;
const { proxy, callback } = post_params;
const url = `${proxy}?callback=${callback}&status=success&data=1`
ctx.response.redirect(url);
}
app.use(route.post('/test/proxy', redirect_test));
app.listen(3000, () => {
console.log('server is running at http://localhost:3000');
})