none
Problem mit Downloadlink aus Intranet RRS feed

  • Frage

  • Hallo,
    per Webservice wird eine Linkliste mit Dateien übergeben, die dann mit JavaScript in einem modalen Bootstrap-Popup angezeigt wird. Die Links werden aus einer Tabelle gelesen und verweisen auf Dateien auf einem Fileserver (Bsp.: '\\Fileserver\Files\Datei1.pdf'):

            function ServiceOK(data) {
                if (DataType == "json") {
                    var myData = JSON.parse(JSON.stringify(data.d));
                    var result = "<ul>";
                    myData.forEach(function (item) {
                        key = item.Key;
                        val = item.Value;
                        result += "<li><a href=" + item.Key + ">" + item.Value + "</a></li>";
                    });
    
                    result += "</ul>"
                    $("#modalFilesBody").html(result);
                }
    Nun ist es aber so, dass der Download nur mit IE oder Edge funktioniert, mit Chrome tut sich gar nix, und Firefox auch nix, außer dass dieser den Filelink total zerhackstückt.

    Chrome zeigt in der Console 'Not allowed to load local resource:..,' an. Das könnte man ja umgehen, wenn man die Option '--allow-access-from-files' einschaltet.

    Prinzipiell gefällt mir diese Vorgehensweise aber sowieso nicht, da hier der Serverpfad im Klartext angezeigt wird (bei Hover über dem Link).

    Gibt es eine andere Möglichkeit eine Datei zum Download anzubieten? Also irgendwie per XMLHttpRequest?

    Ich hoffe, ich konnte mich einigermaßen verständlich ausdrücken.


    Viele Grüße, Volker


    • Bearbeitet Volker S Montag, 26. Juni 2017 11:49
    Montag, 26. Juni 2017 11:48

Antworten

  • Hallo Volker,

    die Browser unterbinden Zugriffe auf lokale Ressourcen in der Regel aus Sicherheitsgründen. Zusätzlich wird das Problem bei verschiedenen Ressourcenquellen (Website bspw. per https://, Dateizugriff lokal per file:///) verschärft.

    Im ersten Schritt würde ich schauen, ob der Link funktioniert, wenn Du mit

    file:///Fileserver/Files/Datei1.pdf

    zugreifst. So sollte ein entsprechender Link eigentlich aussehen.

    Falls das nicht geht oder nicht gewünscht ist, kannst Du auch einfach ein virtuelles Verzeichnis auf dem Webserver erstellen, das auf die Freigabe zeigt und den Link dann umgestalten.

    Das virtuelle Verzeichnis wäre dann bspw. "Files" und zeigt vom Webserver aus auf "\\Fileserver\Files". Den Link gibst Du dann wie folgt an:

    /Datei1.pdf

    Je nachdem, ob Du serverseitig noch damit arbeiten kannst, geht auch ~/Datei1.pdf, wobei Du das vor der Rückgabe auflösen musst.

    Eine weitere Option wäre ein Handler, der über die web.config registriert wird und der dann für alle Requests auf /Files zuständig ist. Der Handler würde in dem Fall die Datei vom Fileserver laden und an den Client senden.

    Genauere Infos kann man dir aber erst geben, wenn Du uns verrätst, welche Art von Webservice Du hier ansprichst und welche ASP.NET Variante (Webforms, MVC, WebPages, WebApi, Core, ...) Du in deinem Projekt verwendest. Die Vorgehensweise unterscheidet sich hier erheblich.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community


    Montag, 26. Juni 2017 14:14
    Moderator

Alle Antworten

  • Hallo Volker,

    die Browser unterbinden Zugriffe auf lokale Ressourcen in der Regel aus Sicherheitsgründen. Zusätzlich wird das Problem bei verschiedenen Ressourcenquellen (Website bspw. per https://, Dateizugriff lokal per file:///) verschärft.

    Im ersten Schritt würde ich schauen, ob der Link funktioniert, wenn Du mit

    file:///Fileserver/Files/Datei1.pdf

    zugreifst. So sollte ein entsprechender Link eigentlich aussehen.

    Falls das nicht geht oder nicht gewünscht ist, kannst Du auch einfach ein virtuelles Verzeichnis auf dem Webserver erstellen, das auf die Freigabe zeigt und den Link dann umgestalten.

    Das virtuelle Verzeichnis wäre dann bspw. "Files" und zeigt vom Webserver aus auf "\\Fileserver\Files". Den Link gibst Du dann wie folgt an:

    /Datei1.pdf

    Je nachdem, ob Du serverseitig noch damit arbeiten kannst, geht auch ~/Datei1.pdf, wobei Du das vor der Rückgabe auflösen musst.

    Eine weitere Option wäre ein Handler, der über die web.config registriert wird und der dann für alle Requests auf /Files zuständig ist. Der Handler würde in dem Fall die Datei vom Fileserver laden und an den Client senden.

    Genauere Infos kann man dir aber erst geben, wenn Du uns verrätst, welche Art von Webservice Du hier ansprichst und welche ASP.NET Variante (Webforms, MVC, WebPages, WebApi, Core, ...) Du in deinem Projekt verwendest. Die Vorgehensweise unterscheidet sich hier erheblich.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community


    Montag, 26. Juni 2017 14:14
    Moderator
  • Hallo Stefan,
    danke für dein Interesse.

    Puh, ich dachte, das wäre etwas einfacher...
    Aber vielleicht habe ich mich ja auch nur etwas verkehrt ausgedrückt.

    Wenn ich den Link mit http:///... in die Browserzeile eingeb, dann funktioniert er nur im FireFox, alllerding macht der 5xSlash draus. IE und Chrome tut sich gar nichts.

    http://... geht mit jedem Browser, sowie auch \\...
    Firefox macht wieder 5xSlash, IE wandelt \ in / um, Chrome zeigts einfach nur an.

    Das Projekt ist ein bereits bestehendes mit WebForms.

    Auf einer Site können in einer "Kategorien Konfiguration" Dateien hochgeladen werden (per VB), die auf einem Fileserver gespeichert werden (nicht in der DB), nur die Informationan dazu werden in einer Tabelle abgespeichert (Pfad,...). Der Link kann also hier beliebig angepasst werden.

    Auf einer anderen Site wird nach Klick auf einen Button (oder was auch immer) ein Modales Popup angezeigt, in dem die zur Verfügung stehenden Downloads angeboten werden. Das wird per JavaScript erzeugt. Der Webservice ist eigentlich nur dazu da, um an die Liste heranzukommen. Das funktioniert ja auch.

    Zuerst das Konstrukt zum Erzeugen der Downloadbuttons:

    Dim divDDOut As New HtmlGenericControl("div") divDDOut.Attributes.Add("class", "dropdown") Dim btnFiles As New HtmlGenericControl("button") With btnFiles.Attributes .Add("Type", "button") .Add("class", "btn-default sk-button") .Add("data-toggle", "modal") .Add("data-target", "#modalFiles") .Add("aria-haspopup", "true") .Add("onclick", "fnGetFiles(" & drKlassenliste.Item("SK_ID") & ")") Dim htmlSpan As New HtmlGenericControl("span") htmlSpan.Attributes.Add("class", "caret") btnFiles.Controls.Add(htmlSpan) tdh.Controls.Add(btnFiles)

    Der Webservice:

    <AspNetCompatibilityRequirements(RequirementsMode:=AspNetCompatibilityRequirementsMode.Allowed)>
    Public Class SKFiles
    <ServiceContract(Namespace:="")>
        <OperationContract()>
        <WebInvoke(ResponseFormat:=WebMessageFormat.Json)>
        Public Function GetFiles(ByVal intSKID As Integer) As Dictionary(Of String, String)
    
            Dim iList As New Dictionary(Of String, String)
            Dim db As New dbQSEntities
            Dim FILES = From f In db.tbl_SK_FILES
                        Where f.SK_ID = intSKID
                        Select f
    
            For Each item In FILES
                If item.GLOBAL Then
                    iList.Add(item.PFAD, item.BEZEICHNUNG)
                Else
                    If item.USER_ID = clSession.USERID Then
                        iList.Add(item.PFAD, item.BEZEICHNUNG)
                    End If
                End If
            Next
    
            Return iList
        End Function
    End Class

    Der Aufruf des WebService per JavaScript:

    var Type; var Url; var Data; var ContentType; var DataType; var ProcessData; var skid; function fnTblAction(elem) { var id = elem.getAttributeNode('id'); alert(elem.title); } function fnGetFiles(ctlID) { Type = "POST"; Url = "/SKFiles.svc/GetFiles"; Data = '{"intSKID": "' + ctlID + '"}'; ContentType = "application/json; charset=utf-8"; DataType = "json"; ProcessData = true; skid = ctlID; CallService(); } function CallService() { $.ajax({ type: Type, url: Url, data: Data, contentType: ContentType, dataType: DataType, processdata: ProcessData, cache: false, success: function (msg) { ServiceOK(msg); }, error: ServiceFailed }); } function ServiceFailed(result) { alert('Fehler beim Abruf der Daten:\nFehler: ' + result.status + '\nMeldung: ' + result.statusText); Type = null; varUrl = null; Data = null; ContentType = null; DataType = null; ProcessData = null; } function ServiceOK(data) { if (DataType == "json") { var myData = JSON.parse(JSON.stringify(data.d)); var result = "<ul>"; myData.forEach(function (item) { key = item.Key val = item.Value; result += "<li><button type='button' class='btn btn-default btn-sm' onclick=fnOpenFile('" + key + "')>download</button>&nbsp" + val + "</li>"; }); result += "</ul>" $("#modalFilesBody").html(result); } }

    Jedenfalls, lange rede, kurzer Sinn: Ich hab´s mit dem von die vorgeschlagenen virtuellen Verzeichnis gelöst.
    Das ging am schnellsten und einfachsten.

            function fnOpenFile(url) {
    
                var strFilename = url.substring(url.lastIndexOf('/') + 1);
                var link = document.createElement("a");
                link.download = strFilename;
                link.target = "_blank";
    
                link.href = "http://servername/Files/" + skid + "/" + strFilename;
                document.body.appendChild(link);
                link.click();
    
                document.body.removeChild(link);
                delete link;
    
            }
     

    Der Link wird vorher noch, beim Upload und abspeichern entsprechend angepasst ("\" durch "/" ersetzt).

    Ich danke dir für deine Hilfe.


    Viele Grüße, Volker


    • Bearbeitet Volker S Dienstag, 27. Juni 2017 08:39
    Dienstag, 27. Juni 2017 08:37