Как стать автором
Обновить

Доступ к буферу обмена операционной системы из веб-приложения

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

Обзор вариантов


Индивидуальный подход

Каждый браузер имеет своё контекстное меню, которое имеет доступ к странице и может быть вызвано поверх логики страницы, и при случае скопировать выделенный текст элемента страницы. В Firefox это реализовано через стандартный плагин clipboard helper, так что вы можете взаимодействовать с ним. В IE имеется прямой доступ через window.clipboardData, что является нарушением безопасности. В остальных браузерах конкретного решения нет.
Недостатки
— под каждый браузер необходимо писать свою реализацию, и не все браузеры вообще имеют такую возможность.

Adobe Flash

Использовать Flash (старый отработанный метод), который позволяет работать с ClipBoard. Для этого, к примеру, создан javascript код ZeroClipBoard (один js и один swf файлы), используемый многими в качестве готового решения.
Недостатки:
— Flash постепенно становится непопулярной технологией и возможно перестанет быть стандартом из-за прихода HTML5
— по умолчанию не позволяет работать с локальным сайтом, нужно настраивать Flash Player для этого у каждого пользователя
— необходимо использовать «crossdomain.xml» для разрешения кросс-доменнного доступа

Microsoft Silverlight

Использовать Silverlight, который аналогично Flash позволяет получать доступ к ClipBoard через свой контекст.
Недостатки:
— Silverlight — это тоже не чистый HTML, поэтому нелюбители этой технологии могут отказаться от данного решения, но он набирает свои обороты и становится популярным.

Реализация через Silverlight


В данной статье я расскажу про третий вариант, причём мы сможем используя Silverlight обращаться к DOM страницы и наоброт. Для этого со стороны Silverlight будем использовать кнопку и текстовое поле.
Почему так, спроситы вы? Почему кнопка, а не Ctrl+C? Дело в том, что на нажатие клавиш Ctrl+C контейнер Silverlight будет реагировать только, если это нажатие будет внутри контейнера(Silverlight в фокусе), а у нас нажатие будет на странице. Во-вторых, Silverlight имеет одно, но существенное ограничение при доступе к ClipBoard, это можно сделать, но только из контекста Silverlight и только с подачи пользователя, т.е. должна быть нажата кнопка или любое другое событие, недоступное из javascript (private), иначе это ничем бы не отличалось от доступа напрямую из javascript (только через вызов silverlight метода).
Кнопка будет записывать текст в ClipBoard. Но как этому событию передать заданный текст. Для этого сначала надо этот текст получить. Можно вызвать javascript метод, который вернёт в качестве результата выделенный текст. Из silverlight можно вызвать javascript-метод, и передать ему параметры-значения через HtmlPage.Window.Invoke, но нельзя напрямую получить результат, поэтому я использовал текстовое поле, в которое вызванный javascript может записать результат.

Порядок работы такой:
  1. Нажатие кнопки в Silverlight
  2. Вызов javascript-метода из метода кнопки, который читает нужное значение и копирует в Silverligh текстовое поле
  3. Возврат в Javascript-метод
  4. Возврат в метод кнопки silverlight
  5. Чтение значения из текстового поля и запись его в буфер обмена.

Со стороны Silverlight


Создаём silverlight-проект типа application, где имеются два объекта
App.xaml — инициализация
<Ваш класс ClipBoard>.xaml — класс, реализующий доступ к ClipBoard

На странице вашего класса создаём два контрола — кнопку, которая будет нажимать для копирования в буфер обмена и невидимое поле. Пример разметки
<Grid x:Name="LayoutRoot" Background="White">
 <Grid.RowDefinitions>
 <RowDefinition />
 </Grid.RowDefinitions>
 <Button Margin="0,0,0,0" Click="Copy" Content="Copy" Height="20" Width="20" />
 <TextBlock x:Name="txtText" Margin="0" Text="{Binding Text}" Width="0" Height="0" />
</Grid>


* This source code was highlighted with Source Code Highlighter.

И логика класса
[ScriptableType]
  public partial class ClipBoardBase : UserControl
  {
    public string JavascriptFunctionName;
    public ClipBoardBase()
    {
      InitializeComponent();
      HtmlPage.RegisterScriptableObject("silverlightClipBoard", this);
      JavascriptFunctionName = "";
    }
    [ScriptableMember]
    public void CopyToTextEdit(string text)
    {
      txtText.Text = text;
    }
    [ScriptableMember]
    private void Copy(object sender, RoutedEventArgs e)
    {
      HtmlPage.Window.Invoke(JavascriptFunctionName);
      Clipboard.SetText(txtText.Text);
    }
  }


* This source code was highlighted with Source Code Highlighter.

[ScriptableType] и [ScriptableMember] — обязательно для класса и метода, если хотите иметь доступ к ним со страницы
HtmlPage.RegisterScriptableObject(«silverlightClipBoard», this) — под указанным именем регистрируется объект на странице и к нему можно будет обращаться(см. ниже)
JavascriptFunctionName — имя функции, которая вызывается для записи значения в текстовое поле, для дальнейшего копирования в буфер обмена.
CopyToTextEdit — будет вызвана со страницы для записи результата в текстовое поле
Copy — метод по нажатию кнопки, в конце копирует в буфер обмена

Это всё, что нужно со стороны silverlight, в результате вы получаете xap файл — контейнер silverlight, который необходимо положить на сервер.

Со стороны javascript

Необходимо:
  • подготовить и создать объект Silverlight на странице
  • подготовить и создать функцию, которая будет вычитывать копируемое в буфер значение со страницы и записывать его в текстовое поле silverlight


для добавление используется файл Silverlight.js — поставляется Microsoft
var silverlightdiv = document.createElement('div');
b = new Object();
b.source = 'путь к xap-файлу';
b.properties = {};
b.properties.version = '4.0.50303';
b.parentElement = silverlightparent;
b.id = 'silverlightClipBoardElement';
b.initParams = 'JavascriptFunctionName=silverlightClipBoardCopyToEdit';
Silverlight.createObjectEx(b);
silverlightClipBoardElement = document.getElementById('silverlightClipBoardElement');


* This source code was highlighted with Source Code Highlighter.

Silverlight.createObjectEx — cоздаёт объект на странице
b.source — относительный путь к xap файлу
b.parentElement — родительский DOM-элемент
b.id — по нему можно найти объект, в котором находится контейнер
b.initParams — начальные параметры, будут переданы в конструктор класса, задаются в виде 'key1=value1;key2=value2', их можно вычитать, я таким образом передаю название функции, которая будет работать на стороне javascript
silverlightClipBoardElement — глобальная переменная для доступа к объекту
Есть и другие параметры, о которых можно прочитать тут
а теперь сама функция для работы с Silverlight
silverlightClipBoardCopyToEdit = function() {
var CopyValue;
// получить значение текста для буфера обмена в CopyValue  
silverlightClipBoardElement.content.silverlightClipBoard.CopyToTextEdit(CopyValue);
};


* This source code was highlighted with Source Code Highlighter.

Посмотрите, как можно обращаться к методу, для этого у DOM-объекта silverlightClipBoardElement обращаемся к объекту, зарегистрированному под именем silverlightClipBoard (см. конструктор класса silverlight), и далее к методу, передавая заветное CopyValue.

Ссылки


Взаимодействие Silverlight и Javascript
Работа с буфером обмена ОС из Silverlight
Теги:
Хабы:
Всего голосов 19: ↑13 и ↓6+7
Комментарии12

Публикации