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

Возможно, вам понадобится использование буфера обмена операционной системы прямо со страницы веб-приложения в браузере. Немного изучив информацию можно обнаружить, что сделать это напрямую со страницы 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

Похожие публикации

AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 12

    +2
    Запись в него [буфер обмена] может быть использована в нехороших целях злоумышленниками.

    Сдается мне, еще опаснее будет чтение буфера: ведь там могут хранится пароли. Большинство программ-паролехранителей, вроде KeePass, используют буфер обмена для выдачи пароля юзеру. После вставки пароля в форму он еще какое-то время лежит в буфере.
      0
      KeePass еще очищает после себя. А в других случаях жутковато, особенно учитывая то, что на ноутбуках обычно используют гибернацию.
        0
        KeePass очищает не сразу, а через 30 секунд по умолчанию. За это время можно успеть угнать. Маловероятно, но можно.
          0
          Или при закрытии программы. У меня кстати 12 секунд по умолчанию, но если мониторить буфер обмена то…
            0
            А это уже недоработка программы (KeePass). Хранить в буфере обмена пароли можно с очень большой оглядкой.
      • НЛО прилетело и опубликовало эту надпись здесь
          +1
          А демка есть? Хочется проверить будет ли работать в MoonLight.
            0
            к сожалению нет, решение писалось к конкретному проекту
            0
            К чему такое решение? Microsoft забросила Silverlight, его % на компах будет только падать. Но и при текущем % установки оно проигрывает перед Flash.
              0
              Т.е. как забросило? Как минимум Silverlight развился во вне-браузерную технологию, вышла 5-версия, это основной фреймворк Windows Phone и, возможно, он станет основным для Windows 8
              Мобильные платформы уже отказались от Flash, а с приходом HTML5 могут отказаться все.
              Возможно и от Silverlight откажутся, но Flash — это уже точно не мейнстрим.
              +1
              Не понял предпосылок выбора Silverlight в замен тому же Flash.
              Flash постепенно становится непопулярной технологией

              Silverlight еще более непопулярный.
              Из коментария выше:
              но Flash — это уже точно не мейнстрим

              Silverlight даже небыл мейнстримом, а уж будет ли таковым — вопрос
              Как-то странно все и однобоко. Вроде задумка была благой — обосновать свой выбор, но вот реализация этой задумки… Сказали бы прямо — Flash не знаю, Silverlight знаю, да и все. Или наоборот — Flash знаю, Silverlight — не очень, решил попробовать…
                0
                Да, наверно, стоило указать и другие предпосылки. Перевесило то, что в нашем проекте Silverlight обязателен, так как часть фреймворка работает на нём.
                Я также попробовал и Flash, а конкретно, ZeroClipboard, но были ограничения в использовании и визуально они работают немного по-разному. На Silverlight готового решения не нашёл, и собрал несколько идей в одну.

              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

              Самое читаемое