Advertisement
  1. Code
  2. JavaScript
  3. Node

Добавление возможности шаринга (публикации) контента в социальных сетях в одностраничном приложении Node.js

Scroll to top
Read Time: 10 min

() translation by (you can also view the original English article)

Single-Page Applications (SPAs) (* одностраничные приложения. Здесь и далее примеч. пер.) работают благодаря визуализации шаблонов на клиентской стороне. Это придает быстродействие опыту взаимодействия пользователя с приложением. Недавно компания Google объявила, что они осуществляют веб-скрейпинг и исполняют код JavaScript так же, как бы это делал обычный пользователь. В результате чего веб-скрейпинг (* вытягивание веб-данных из веб-страниц) сайтов, работающих благодаря фреймворкам для создания одностраничных приложений (Angular, Ember и Vue и т.д.), осуществляется без наказаний со стороны Google.

Помимо поисковых роботов для видимости вашего сайта также необходимы и другие веб-пауки, а именно роботы для осуществления шаринга подробного контента в социальных сетях. Они полагаются на мета-теги и до сих пор не учитывают код JavaScript.

В этом руководстве мы создадим дополнительный модуль для размещения маршрута и воспроизведения шаблона для вашего сервера Express и Node.js, который вы можете использовать с большинством фреймворков для создания одностраничных приложений. Благодаря этому модулю ваш сайт сможет предоставить пользователям возможность осуществления шаринга подробного контента в Twitter, Facebook и Pinterest.

Предупреждаю

В данном руководстве речь идет только о веб-роботах, которые извлекают информацию для добавления в социальные сети. Не пробуйте использовать эти приемы для веб-пауков поисковых систем. Компании поисковых систем могут серьезно отреагировать на подобное поведение и посчитать его спамом или обманом, в результате чего рейтинг вашего сайта может быстро понизиться.

Подобным образом при шаринге подробного контента в социальных сетях убедитесь, что вы представляете контент таким образом, что то, что видит пользователь, совпадает с тем, что читает веб-робот. При невыполнении этого условия на ваше приложение могут быть наложены ограничения со стороны сайтов социальных сетей.

Шаринг подробного контента в социальных сетях

Если вы опубликуете новую статью в Facebook и добавите URL (* Uniform Resource Locator - унифицированный указатель [местонахождения информационного] ресурса), то веб-робот Facebook прочитает HTML-код и будет в нем искать мета-теги для протокола OpenGraph. Ниже представлен пример для главной страницы Envato Tuts+ :

Envato Tuts+ Social Share ScreenshotEnvato Tuts+ Social Share ScreenshotEnvato Tuts+ Social Share Screenshot

При просмотре HTML-кода мы видим в теге head соответствующие теги для создания этого превью:

1
<meta content="Envato Tuts+" property="og:title">
2
<meta content="Envato Tuts+ teaches creative and technical skills across many topics to millions of people worldwide. We offer tutorials, articles, news and insights that help you take your knowledge to the next level." property="og:description">
3
<meta content="http://static.tutsplus.com/assets/favicon-8b86ba48e7f31535461f183680fe2ac9.png" property="og:image">

Pinterest использует тот же протокол (OpenGraph), что и Facebook. Поэтому их механизмы для шаринга контента работают довольно сходным образом.

В Twitter концепция шаринга контента имеет название 'карточка', и в Twitter есть несколько ее различных реализаций в зависимости от способа представления вашего контента. Ниже приведен пример карточки Twitter из GitHub:

Screenshot of Twitter Card generated by a GitHub pageScreenshot of Twitter Card generated by a GitHub pageScreenshot of Twitter Card generated by a GitHub page

А вот HTML - код для ее создания:

1
<meta content="@github" name="twitter:site">
2
<meta content="summary" name="twitter:card">
3
<meta content="NodeRedis/node_redis" name="twitter:title">
4
<meta content="redis client for node. Contribute to node_redis development by creating an account on GitHub." name="twitter:description">
5
<meta content="https://avatars1.githubusercontent.com/u/5845577?v=3&amp;s=400" name="twitter:image:src">

Примечание: GitHub использует прием, подобный тому, что описывается в данном руководстве. Имеется небольшое отличие кода HTML в теге, атрибут name которого имеет значение twitter:description. Мне необходимо изменить название агента пользователя, как показано позже в этом руководстве, чтобы получить соответствующий мета-тег.

Препятствия при воспроизведении контента на стороне клиента

Добавление мета-тегов не представляет трудностей, если вас устраивает добавление только одного заголовка, описания или изображения в социальных сетях для целого сайта. Просто впишите значения мета-тегов прямо в head вашего HTML-документа. Однако, к счастью, вы создаете намного более сложный веб-сайт и хотите, чтобы публикуемый подробный контент в социальных сетях изменялся в зависимости от значения URL-адреса (который, наверняка, устанавливается при помощи HTML5 History API (* позволяет изменять URL веб-сайта без перезагрузки всей страницы), которым манипулирует ваш фреймворк).

Вы сразу могли бы попробовать создать ваш шаблон и добавлять значения в мета-теги так же, как вы бы делали с любым другим контентом (* при помощи JavaScript). Поскольку на данный момент веб-пауки, извлекающие эту информацию, не выполняют код JavaScript, то при попытке опубликовать контент в социальных сетях в вашем шаблоне останутся прежние значения тегов вместо предполагаемых.

Для того чтобы ваш сайт могли читать веб-пауки, мы создаем промежуточное ПО, которое определяет агент пользователя веб-робота, используемого социальной сетью для добавления контента, и затем создаем дополнительный маршрут, в ответ на запросы по которому веб-роботу будет преподнесен соответствующий контент. При этом не задействуется ваш фреймворк для SPA.

Промежуточное ПО для определения агента пользователя

Клиенты (роботы, веб-пауки, веб-браузеры) отправляют строку User Agent (UA) (* агент пользователя) в  заголовках HTTP каждого запроса. Предполагается, что благодаря этому можно будет определить тип программного обеспечения клиента. В то время как у веб-браузеров имеется огромное разнообразие строк UA, веб-боты более-менее стабильны в этом вопросе. Facebook, Twitter и Pinterest придают огласке строки UA своих веб-ботов из уважения к разработчикам.

В Express значение строки UA содержится в объекте запроса req в свойстве user-agent. Я использую регулярное выражение для идентификации различных веб-ботов, которым я хотел бы предоставить альтернативный контент. Мы поместим его в промежуточное ПО. Промежуточное ПО подобно маршрутам, однако для него не требуется путь или метод и в нем (обычно) запрос передается к другому промежуточному ПО или маршруту. В Express маршруты и промежуточное ПО выполняются последовательно, поэтому расположите следующий код выше любого другого маршрута в вашем приложении Express.

1
app.use(function(req,res,next) {
2
  var
3
    ua = req.headers['user-agent'];
4
5
  if (/^(facebookexternalhit)|(Twitterbot)|(Pinterest)/gi.test(ua)) {
6
    console.log(ua,' is a bot');
7
  } 
8
9
 next();
10
});

Вышеуказанное регулярное выражение осуществляет поиск символов “facebookexternalhit”, “Twitterbot” или “Pinterest” в начале строки UA. Если символы найдены, то значение строки UA выводится в консоль.

Ниже приводится код всего сервера:

1
var
2
  express   = require('express'),
3
  app       = express(),
4
  server;
5
6
app.use(function(req,res,next) {
7
  var
8
    ua = req.headers['user-agent'];
9
10
  if (/^(facebookexternalhit)|(Twitterbot)|(Pinterest)/gi.test(ua)) {
11
    console.log(ua,' is a bot');
12
  } 
13
14
  next();
15
});
16
17
app.get('/',function(req,res) {
18
  res.send('Serve SPA');
19
});
20
21
server = app.listen(
22
  8000,
23
  function() {
24
    console.log('Server started.');
25
  }
26
);

Тестирование вашего промежуточного ПО

В Chrome перейдите на ваш новый сервер (URL-адресом которого должен быть http://localhost:8000/). Откройте DevTools и включите ‘Device Mode’ (* режим устройства), кликнув по иконке смартфона в верхней левой части панели разработчика.

Screenshot of Chrome DevTools showing the location of Device ModeScreenshot of Chrome DevTools showing the location of Device ModeScreenshot of Chrome DevTools showing the location of Device Mode

На панель инструментов устройства введите строку “Twitterbot/1.0” в поле для редактирования значения UA.

Screenshot of Chrome DevTools illustrating the location of the input box for user agentsScreenshot of Chrome DevTools illustrating the location of the input box for user agentsScreenshot of Chrome DevTools illustrating the location of the input box for user agents

Теперь перезагрузите страницу.

В этот момент вы должны увидеть “Serve SPA” на странице, однако при просмотре результата в консоли вашего приложения Express вы должны увидеть:

Twitterbot/1.0 is a bot

Альтернативная маршрутизация

Теперь, когда мы можем определять веб-ботов, давайте создадим альтернативный маршрут. В Express может использоваться множество маршрутизаторов, часто используемых для разделения маршрутизаторов в зависимости от пути. В нашем случае мы собираемся использовать маршрутизатор немного по-особенному. Маршрутизаторы представляют из себя по сути промежуточное ПО, поэтому они принимают объекты req, res и next, как и остальное промежуточное ПО. Идея здесь состоит в том, чтобы сгенерировать другой набор маршрутов с теми же путями.

1
nonSPArouter = express.Router();
2
nonSPArouter.get('/', function(req,res) {
3
  res.send('Serve regular HTML with metatags');
4
});

Наше промежуточное ПО также необходимо изменить. Вместо того, чтобы просто выводить сообщение о том, что клиент является веб-ботом, мы теперь будем пересылать запрос к следующему маршрутизатору и, что важно, передавать его далее при помощи вызова next() только если условие при проверке UA не выполнилось. Таким образом, если вкратце, то для веб-ботов имеется один маршрутизатор, а для всех остальных клиентов - стандартный маршрутизатор, который передает код одностраничного приложения.

1
var
2
  express   = require('express'),
3
  app       = express(),
4
  
5
  nonSPArouter      
6
            = express.Router(),
7
  server;
8
9
nonSPArouter.get('/', function(req,res) {
10
  res.send('Serve regular HTML with metatags');
11
});
12
13
app.use(function(req,res,next) {
14
  var
15
    ua = req.headers['user-agent'];
16
17
  if (/^(facebookexternalhit)|(Twitterbot)|(Pinterest)/gi.test(ua)) {
18
    console.log(ua,' is a bot');
19
    nonSPArouter(req,res,next);
20
  } else {
21
    next();
22
  }
23
});
24
25
app.get('/',function(req,res) {
26
  res.send('Serve SPA');
27
});
28
29
server = app.listen(
30
  8000,
31
  function() {
32
    console.log('Server started.');
33
  }
34
);

Если мы протестируем приложение по той же схеме, как и выше, то при указании значением UA строки Twitterbot/1.0 браузер покажет при перезагрузке следующее:

Serve regular HTML with metatags

Тогда как при использовании стандартного UA Chrome вы увидите:

Serve SPA

Мета-теги

Как мы рассматривали выше, добавление подробного контента в социальные сети осуществляется благодаря мета-тегам внутри заголовка вашего HTML-документа. Поскольку вы создаете одностраничное приложение, то, должно быть, у вас даже не установлен шаблонизатор. В этом руководстве мы будем использовать jade. Jade является довольно простым языком для написания шаблонов, в котором пробелы и табуляция играют роль и не требуется использование закрывающих тегов. Мы можем установить его при помощи команды:

npm install jade

В исходном коде нашего сервера добавьте ту строку перед строкой app.listen.

app.set('view engine', 'jade');

Теперь мы собираемся добавить информацию, которую хотели бы передавать только веб-боту. Мы изменим nonSPArouter. Поскольку мы установили механизм представления в методе set объекта app, метод res.render будет выполнять визуализацию шаблонов на jade.

Давайте создадим небольшой jade-шаблон для представления информации веб-ботам, которые  осуществляют шаринг контента в социальных сетях.

1
doctype html
2
html
3
  head
4
    title= title
5
    meta(property="og:url"  name="twitter:url" content= url)
6
    meta(property="og:title" name="twitter:title" content= title)
7
    meta(property="og:description" name="twitter:description" content= descriptionText)
8
    meta(property="og:image" content= imageUrl)
9
    meta(property="og:type" content="article")
10
    meta(name="twitter:card" content="summary")
11
  body
12
    h1= title
13
    img(src= img alt= title)
14
    p= descriptionText

Большую часть кода составляют мета-теги, однако вы можете также заметить, что я добавил информацию и в тело документа. На момент написания этого руководства считается, что все веб-боты для добавления контента в социальных сетях смотрят только на мета-теги. Однако добавление информации в отчасти читабельном для человека виде является установившейся практикой и делается на случай, если необходима будет проверка кода человеком через некоторое время.

Сохраните шаблон в папку для представлений вашего приложения и назовите его bot.jade. Имя файла  без расширения (‘bot’) будет первым параметром метода res.render.

Несмотря на то, что локальная разработка важна, вам необходимо будет поместить ваше приложение в его конечное местоположение для полноценной отладки ваших мета-тегов. Готовая к развертыванию версия нашего крошечного сервера выглядит следующим образом:

1
var
2
  express   = require('express'),
3
  app       = express(),
4
  
5
  nonSPArouter      
6
            = express.Router(),
7
  server;
8
9
nonSPArouter.get('/', function(req,res) {
10
  var
11
    img   = 'placeholder.png';
12
    
13
  res.render('bot', { 
14
    img       : img,
15
    url       : 'https://bot-social-share.herokuapp.com/',
16
    title     : 'Bot Test', 
17
    descriptionText 
18
              : 'This is designed to appeal to bots',
19
    imageUrl  : 'https://bot-social-share.herokuapp.com/'+img
20
  });
21
});
22
23
app.use(function(req,res,next) {
24
  var
25
    ua = req.headers['user-agent'];
26
27
  if (/^(facebookexternalhit)|(Twitterbot)|(Pinterest)/gi.test(ua)) {
28
    console.log(ua,' is a bot');
29
    nonSPArouter(req,res,next);
30
  } else {
31
    next();
32
  }
33
});
34
35
app.get('/',function(req,res) {
36
  res.send('Serve SPA');
37
});
38
app.use('/',express.static(__dirname + '/static'));
39
app.set('view engine', 'jade');
40
server = app.listen(
41
  process.env.PORT || 8000,
42
  function() {
43
    console.log('Server started.');
44
  }
45
);

Также обратите внимание на то, что я использую промежуточное ПО express.static для передачи изображений из папки /static.

Отладка вашего приложения

Как только вы выполнили дистанционную инсталляцию вашего приложения на какой-то сервер для публичного доступа, вам необходимо убедиться, что ваши мета-теги работают как положено.

Для начала вы можете протестировать при помощи инструмента Facebook Debugger. Введите ваш URL-адрес и нажмите 'Fetch new scrape information' (* Получить новую информацию об URL).

Вы должны увидеть нечто подобное:

Screenshot of the Facebook open graph debuggerScreenshot of the Facebook open graph debuggerScreenshot of the Facebook open graph debugger

Далее вы можете перейти к тестированию вашей карточки Twitter при помощи инструмента Twitter Card Validator. Для использования этого инструмента вам необходимо будет войти в ваш аккаунт Twitter.

Screenshot of the Twitter Card ValidatorScreenshot of the Twitter Card ValidatorScreenshot of the Twitter Card Validator

Pinterest предоставляет отладчик, но этот пример не будет работать в том виде, в каком он сейчас, поскольку Pinterest позволяет использовать «подробные Пины» для всех URL-адресов, кроме URL-адреса вашей главной страницы.

Следующие шаги

В фактической реализации приложения вам необходимо будет справиться с интеграцией вашего источника данных и маршрутизации. Лучше всего будет посмотреть на маршруты, указанные в коде одностраничного приложения, и создать альтернативную версию для всего, чем, на ваш взгляд, пользователи могли бы поделиться. После настройки маршрутов для передачи контента, которым, скорее всего, пользователи захотят поделиться, добавьте мета-теги в ваш основной шаблон, которые будут выполнять роль запасного варианта в ситуации, когда кто-либо делится страницей, возможность добавления в социальных сети которой не предполагалась.

Несмотря на то, что Pinterest, Facebook и Twitter составляют крупную долю рынка социальных сетей, у вас может возникнуть желание интегрироваться и с другими сервисами. Некоторые сервисы действительно публикуют названия своих веб-роботов для осуществления шаринга контента в социальных сетях, а некоторые могут и скрывать. Для определения агента пользователя вы можете использовать команду console.log и посмотреть на результат в консоли. Попробуйте сначала сделать это на сервере, не предназначенном для публикации вашего сайта для широких масс, поскольку при определении агента пользователя на высоконагруженных сайтах для этого может быть неподходящий момент. После этого вы можете изменить регулярное выражение в нашем промежуточном ПО, чтобы отследить и нового агента пользователя.

Подробные публикации в социальных сетях могут быть отличным способом для привлечения посетителей на ваш необычный сайт, основой которого служит одностраничное приложения. Избирательно направляя веб-роботов к машиночитаемому контенту, вы можете передать им подходящую информацию.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.