ты выучишь
- Знакомство с распространенными решениями междоменной технологии
- postMessage реализует междоменную связь
- Как внедрить чат-бота
- Node создает локальный сервер для рендеринга страниц и междоменных
- Ответьте на идеи дизайна корпуса
Предварительный просмотр эффекта
текст
1. Знакомство с распространенными решениями междоменной технологии
Первое, что следует подчеркнуть, это то, что все ограничения междоменной безопасности действуют на стороне браузера, а на стороне сервера ограничений междоменной безопасности нет. Наши широко используемые междоменные технологии в основном включают следующее:
- кросс-доменный JSONP
- междоменный iframe+домен
- Междоменный обратный прокси-сервер nginx
- cors перекрестный домен
- postMessage кросс-доменный
Междоменный JSONPПринцип запроса заключается в динамическом создании тега скрипта, а затем использовании src скрипта для получения данных между доменами без ограничений политики одного и того же происхождения. JSONP в основном состоит из функции обратного вызова и данных. Имя callback-функции обычно указывается в запросе. Данные — это данные 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 очень просто реализовать кросс-доменный, он поддерживает только запросы на получение, что ограничивает объем передаваемых данных.cors перекрестный доменЭто наиболее распространенный метод локальной отладки, который мы используем в настоящее время.Принцип заключается в том, чтобы установить поле Access-Control-Allow-Origin заголовка ответа на стороне сервера, чтобы браузер обнаружил Access-Control-Allow-Origin в заголовок, чтобы вы могли пересекать домен.
Что касается проблемы двух запросов в сети после того, как мы настроили cors, то на самом деле речь идет о cors cross-domainзапросить предварительную проверку, разделенные на простые просьбы и непростые просьбы.Эти знания можно почерпнуть из одной статьи, а интересующиеся могут изучить их самостоятельно.
2. postMessage реализует междоменную связь
Метод window.postMessage() обеспечивает безопасную связь между источниками. Как правило, сценарии для двух разных страниц могут взаимодействовать друг с другом только в том случае, если исполняющие их страницы расположены на одном и том же протоколе, номере порта и хосте (модуль Document.domain двух страниц имеет одинаковое значение). . Метод window.postMessage() предоставляет контролируемый механизм для обхода этого ограничения и безопасен при правильном использовании.
По сути, postMessage() основан на механизме событий сообщения для реализации междоменной связи.Он принадлежит самой форме сообщения, такой как окно и окно фрейма, встроенного в окно.Основное использование выглядит следующим образом:
someWindow.postMessage(message, targetOrigin, [transfer]);
Введение параметра:
- someWindowСсылка на окно, такое как свойство contentWindow элемента iframe, объект окна, возвращаемый при выполнении команды window.open, или именованный или численно индексированный window.frames.
- messageДанные для отправки в другие окна. Означает, что вы можете безопасно передавать объект данных в целевое окно без каких-либо ограничений, не сериализуя его самостоятельно.
- targetOriginУкажите, какие окна могут получать события сообщения через свойство origin окна, и его значением может быть строка "*" (представляющая неограниченное количество). Неспособность указать точную цель приведет к проблемам безопасности, таким как утечка данных.
- transferпредставляет собой строку объектов Transferable, передаваемых вместе с сообщением. Право собственности на эти объекты будет передано получателю сообщения, а отправитель больше не сохранит право собственности
Мы можем прослушивать сообщения следующими способами:
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)
Наше событие имеет следующие основные свойства:
- dataОбъекты, переданные из других окон
- originПроисхождение окна отправителя сообщения при вызове postMessage.Эта строка объединяется из протокола, "://", имени домена, ": номер порта"
- sourceссылка на объект окна, который отправил сообщение; вы можете использовать это, чтобы установить двустороннюю связь между двумя окнами с разными источниками
3. Внедрите чат-бот
После ознакомления с вышеуказанными знаниями мы начинаем писать демонстрацию нашего чат-бота. Сначала пишем два 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 в страницу a в виде iframe. Конкретная структура выглядит следующим образом:
Сначала мы отправляем сообщение на страницу b, отправляя кнопку и поле ввода на странице a. Общая структура выглядит следующим образом:
<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>
Мы можем получить ссылку на форму страницы B через contentWindow iframe, а затем вызвать postMessage в событии нажатия кнопки отправки, чтобы отправить данные в B. Структура страницы B выглядит следующим образом:
<body>
<div class="content">
<h4>Lab智能机器人</h4>
<div class="content-inner"></div>
</div>
<script>
// 语料库
const pool = [];
window.addEventListener("message", receiveMessage, false);
let content = document.querySelector('.content-inner');
let initContentH = content.scrollHeight;
let _ = (data) => JSON.stringify(data);
function createChat(type, mes) {
let dialog = document.createElement('div');
dialog.className = type === 0 ? 'dialog robot' : 'dialog user';
let content = type === 0 ? `
<span class="tx">${type === 0 ? 'lab' : 'user'}</span>
<span class="mes">${mes}</span>
` : `
<span class="mes">${mes}</span>
<span class="tx">${type === 0 ? 'lab' : 'user'}</span>
`;
dialog.innerHTML = content;
return dialog
}
function scrollTop(el, h) {
if(el.scrollHeight !== h) {
el.scrollTop = h + 100;
}
}
function receiveMessage(event){
// 兼容其他浏览器
let origin = event.origin || event.originalEvent.origin;
if(origin === 'http://127.0.0.1:8000') {
let data = JSON.parse(event.data);
if(data && !data.text) {
mes = { text: '你好,我是机器人Lab,请问有什么可以帮到您的吗?' };
event.source.postMessage(_(mes), event.origin)
content.appendChild(createChat(0, mes.text))
}else {
content.appendChild(createChat(1, data.text))
scrollTop(content, initContentH)
setTimeout(() => {
content.appendChild(createChat(0, '正在解决'))
scrollTop(content, initContentH)
}, 2000);
}
}
}
</script>
</body>
Разбираем данные страницы a на странице b и делаем соответствующие ответы. Таким образом, наш базовый чат-бот реализован.
4. Идеи дизайна корпуса ответов
Что касается того, как анализировать и отвечать, когда мы отправляем сообщение на странице a, страница b может иметь следующие идеи:
- Реализовано через внутренний интерфейс, то есть мы можем передать данные a в качестве параметра внутреннему интерфейсу и позволить серверу реализовать возврат необходимых данных Это широко используется в роботах с искусственным интеллектом.
- Чистая фронтенд реализация. Внешний интерфейс определяет корпус ответа и получает ответ посредством сопоставления ключевых слов, которое обычно используется для ответа на распространенные заданные вопросы.
5. Реализуйте сменные
Подключаемый означает, что страницу можно использовать на разных платформах. Таким образом, мы можем установить исходный белый список, нужно только инкапсулировать страницу b, другие системы могут использовать метод, аналогичный странице a, и предоставить только интерфейс для отправки информации, чтобы мы могли использовать его на разных уровнях.
наконец
Если вы хотите узнать больше о внешних интерфейсах и реальных боевых действиях, таких как webpack, node, gulp, css3, javascript, nodeJS, canvas и т. д., присоединяйтесь к нам в общедоступной учетной записи «Интересный интерфейс», чтобы узнать и обсудить вместе и исследовать границы интерфейса вместе.
больше рекомендаций
- Продвижение переменной, продвижение объявления функции и подробное объяснение области действия переменной в «Сводке по интерфейсу боя».
- «Резюме фронтенда», как изменить URL-адрес, не обновляя страницу
- Борьба с конфигурацией и использованием накопительного инструмента для упаковки внешних компонентов/библиотек
- Картинка, чтобы научить вас быстро играть в vue-cli3
- Vue advanced advanced series — играйте с vue и vuex с машинописным текстом
- Быстро осваивайте новые функции es6+ и основной перечень грамматики es6
- Реализовать проект полного стека CMS от 0 до 1 на основе nodeJS (включено)
- Реализовать проект полного стека CMS от 0 до 1 на основе nodeJS (средний)
- Реализовать проект полного стека CMS от 0 до 1 на основе nodeJS (ниже)
- Сведения о запуске на стороне сервера для реализации проекта полного стека CMS от 0 до 1 на основе nodeJS
- Использование Angular8 и API карты Baidu для разработки «списка туров»
- Краткое изложение основных знаний по теме "Продвинутое программирование на JavaScript"
- Используйте css3, чтобы реализовать фоновую анимацию потрясающего интервьюера (расширенный исходный код)
- 5 минут, чтобы научить вас писать фиктивный сервер данных с помощью nodeJS
- Научу вас использовать 200 строк кода, чтобы написать любовную мини-игру Dou Pin Le H5 (с исходным кодом)