由于笔者之前的项目中接触过聊天机器人的项目,主要实现机器人客服模块,以及支持跨多平台使用的目的,所以特地总结一下,希望有所收获。
你将学到
效果预览
正文
1. 跨域技术常用方案介绍
首先要强调的是跨域的安全限制都是对浏览器端来说的,服务器端是不存在跨域安全限制的。我们常用的跨域技术主要有如下几种:
JSONP实现跨域请求的原理就是动态创建script标签,然后利用script的src 不受同源策略约束来跨域获取数据。JSONP 主要由回调函数和数据两部分组成。回调函数的名字一般是在请求中指定的。而数据就是传入回调函数中的 JSON 数据。我们一般可以在全局定义一个回调函数,然后在script标签里传入回调函数即可:
- window.handleData = function(data){
- // ...
- }
- let script = document.createElement("script");
- script.src = "https://xxxx.com/v0/search?q=xuxi&callback=handleData";
- document.body.insertBefore(script, document.body.firstChild);
这样我们就能在回调函数handleData中拿到服务器接口返回的数据了。
虽然jsonp实现跨域方式很简单,但是只支持get请求,对传输的数据量有一定限制。cors跨域是目前我们用的比较多的本地调试方式,原理就是在服务端设置响应头header的Access-Control-Allow-Origin字段,这样浏览器检测到header中的Access-Control-Allow-Origin,这样就可以跨域了。
至于我们设置了cors之后在network中出现了两次请求的问题,其实涉及到cors跨域的请求预检,分为简单请求和非简单请求两种,这块知识可以单独抽离出一篇文章,感兴趣的可以自己学习了解一下。
2. postMessage实现跨域通信
本质上说postMessage()是基于消息事件机制来实现跨域通信,它隶属于消息窗体本身,比如window以及window内嵌的frame的window,基本使用形式如下:
- someWindow.postMessage(message, targetOrigin, [transfer]);
参数介绍:
我们可以通过如下方式来监听message:
- window.addEventListener("message", receiveMessage, false);
- function receiveMessage(event){
- let origin = event.origin || event.originalEvent.origin;
- if (origin !== "http://aaa:8080")
- return;
- // ...
- console.log(event.data)
- }
- // 派发消息的页面
- winB.postMessage(_({text: '休息休息'}), origin)
我们的event里有如下几个核心的属性:
3. 实现聊天机器人
在熟悉以上知识点之后,我们开始来写我们聊天机器人的demo。首先我们写两个html,分别为a.html和b.html,然后用node分别代理两个不同页面,设置不同端口:
- // a.js
- //依赖一个http模块,相当于java中的import,与C#中的using
- var http = require('http');
- var fs = require('fs');
- var { resolve } = require('path');
- //创建一个服务器对象
- server = http.createServer(function (req, res) {
- //设置请求成功时响应头部的MIME为纯文本
- res.writeHeader(200, {"Content-Type": "text/html"});
- //向客户端输出字符
- let data = fs.readFileSync(resolve(__dirname, './a.html'))
- res.end(data);
- });
- //让服务器监听本地8000端口开始运行
- server.listen(8000,'127.0.0.1');
- console.log('http://127.0.0.1:8000')
- // b.js
- // ...
- server.listen(8001,'127.0.0.1');
由上可知我们a.html代理在8000端口下,b.html代理在8001端口下,由浏览器的同源策略可知他们存在跨域问题。
跨域实现之后我们可以开始搭建页面层级了,我们这里将b页面以iframe的形式嵌入到a页面,具体结构如下:
这样我们就可以愉快的搭建postMessage体系了。首先我们在a页面通过发送按钮和输入框将消息发送给b页面,大致结构如下:
- <body>
- <div class="wrap">
- <iframe src="http://127.0.0.1:8001" frameborder="0" id="b"></iframe>
- <div class="control">
- <input type="text" placeholder="请输入内容" id="ipt">
- <span id="send">发送</span>
- </div>
- </div>
- <script>
- window.onload = function() {
- let origin = 'http://127.0.0.1:8001';
- let _ = (data) => JSON.stringify(data);
- let winB = document.querySelector('#b').contentWindow;
- let sendBtn = document.querySelector('#send');
- sendBtn.addEventListener('click', (e) => {
- let text = document.querySelector('#ipt');
- winB.postMessage(_({text: text.value}), origin)
- text.value = '';
- }, false)
- winB.postMessage(_({text: ''}), origin)
- }
- </script>
- </body>
查看表结构,sbtest1有主键、k_1二级索引、i_c二级索引 CREATE TABLE `sbtest1` ...
2020年对于云计算行业来说是突破性的一年,因为公共云供应商增加了收入,而疫情...
定义 this是函数运行时自动生成的内部对象,即调用函数的那个对象。(不一定很准...
最近,DevOps的采用导致了企业计算的重大转变。除无服务器计算,动态配置和即付...
本文转载自网络,原文链接:https://mp.weixin.qq.com/s/vlOUg46B5bcmToX-fjavJQ...
中国最?好的一朵云飘进了华瑞银行。阿里云将进一步助力华瑞银行All in Cloud。 -...
一、PostgreSQL行业位置 一 行业位置 首先我们看一看RDS PostgreSQL在整个行业当...
9月17日,2020云栖大会上,阿里云正式发布工业大脑3.0。 阿里云智能资深产品专家...
在TOP云(zuntop.com)科技租赁过服务器的站长都知道独立服务器在价格上比VPS主...
很长时间没有更新原创文章了,但是还一直在思考和沉淀当中,后面公众号会更频繁...