09/09/2010

htmlfile: Access Denied

Home

FileUploader to kontrolka, która umożliwia wybranie pliku przez użytkownika i przesłanie go na serwer. Po umieszczeniu na stronie renderuje się do pola tekstowego i przycisku Przeglądaj. Ja chciałem uzyskać efekt, w którym kontrolka ta jest ukryta, użytkownik naciska pewien przycisk, wyświetlane jest okienko do wyboru pliku, a następnie plik przesyłany jest na serwer. Zrobiłem to przy pomocy odrobiny JavaScript'u.
    function chooseFile()
    {
        var uploader = document.getElementById("<%= this.Uploader.ClientID %>");
        uploader.click();
    }

    function submitFile() 
    {
        document.forms[0].submit();
    }
Pierwsza funkcja chooseFile znajduje na stronie kontrolkę i wymusza kliknięcie na nią czyli powoduje wyświetlenie okienka do wyboru pliku. Druga funkcja po prostu przesyła stronę na serwer. Kontrolka i przycisk zostały osadzone na stronie w sposób pokazany poniżej:
    ...
    <asp:Button ID="Upload" runat="server" OnClientClick="chooseFile();" Text="Wybierz plik"/>
    ...
    <asp:FileUpload ID="Uploader" runat="server" style="display:none" onchange="submitFile();" />
     ...
Dzięki ustawieniu atrybutu display na wartość none kontrolka renderuje się do kodu HTML nie jest natomiast widoczna dla użytkownika. Po napisaniu kodu uruchamiam stronę, wybieram przycisk Wybierz plik i ku mojemu zadowoleniu pojawia się okienko do wyboru pliku. Wybieram interesujący mnie plik i na tym niestety kończy się zabawa, a pojawia się problem. W linii zawierającej document.forms[0].submit(); raportowany jest błąd htmlfile: Access Denied.

Sprawdzam jeszcze raz te kilka linijek kodu ale wyglądają prawidłowo. No dobrze, a może błąd jest spowodowany tym, że schowałem kontrolkę. Usuwam atrybut style i próbuję jeszcze raz ale błąd znowu się pojawia. Teraz kontrolka jest widoczna, więc sprawdzam co się stanie kiedy nacisnę przycisk Przeglądaj samemu, a nie przy pomocy JavaScript'u. Próbuję i tym razem wybrany plik został przesłany na serwer! Dla pewności powtarzam eksperyment jeszcze raz i ponownie sukces. Innymi słowy błąd pojawia się jeśli kontrolka do wyboru pliku zostanie kliknięta z poziomu kodu.

Więcej pomysłów nie mam, a więc zaglądam do Google i od razu widzę kilku nieszczęśników z podobnym problemem jak mój. Niestety zamiast rozwiązania problemu znajduję tylko informację, że błąd ten związany jest z jakimś mechanizmem bezpieczeństwa, który nie pozwala wysyłać plików bez wiedzy użytkownika. Sprawdzam jeszcze jak sytuacja wygląda w innych przeglądarkach (Opera i Firefox) i błąd się nie pojawia ale to dlatego, że nie działa kod uploader.click(); i okienko do wyboru pliku nie wyświetla się.

Jedyne co mi jeszcze przychodzi do głowy do wypróbowanie innych kontrolek do wyboru plików np.: Talerik'a. Dopóki nie znajdę obejścia problemu będę natomiast stosował tradycyjne podejście do zagadnienia czyli pozwolę użytkownikowi samemu nacisnąć przycisk.

2 comments:

Maciej Aniserowicz said...

Ostatnio używałem uploader Uploadify - plugin do jquery. Polecam wypróbować, dość prosto można osiągnąć całkiem fajne efekty. Jedyna wada - wymaga zainstalowanego flasha... ale są podobne 'uploadery' bez takiego wymogu.

Unknown said...

Mozna to obejsc tak:
1. FileUpload i Button ustawic w css jako absolute, tak by przyciski obu kontrolek sie pokrywaly

2. Ustawic z-index Uploadera na 2, a Buttona na 1 - wtedy Uploader bedzie na gornej warstwie

3. Ustawic filtr opacity na 0 [filter: alpha(opacity=0); opacity: 0;] - dzieki temu Uploader bedzie niewidoczny ale mozna bedzie w niego klikac ;)

Dzieki temu klikamy w niewidoczny Uploader majac wrazenie ze klikamy w Button. Dalej to juz tak jak masz

Podpatrzylem to kiedys w kontrolce Telerika, oni jeszcze przy poruszaniu mysza na Buttonie (onMouseMove) przesuwaja niewidocznego Uploadera - tak ze zawsze w niego klikniesz niezaleznie od wielkosci przycisku.

Post a comment