Dateidownload und AJAX
ohas
- javascript
folgendes problemchen: ich sende per jquery ajax einen get request
an den server zum download einer datei. (ungeachtet der tatache, dass es ungeignet ist dafür, geht es darum einen workaround zu finden, denn AJAX ist wegen authentifizierung "pflicht" :-)) der server antwortet per
content-distribution attachment etc. und schickt die datei als antwort zurück,
ABER ich erwarte eigentlich, dass sich dann ein pop-up-dialog zum speichern der
datei öffnet, was es nicht tut.
hier die daten:
----------------------------------------------------------------
JQUERY AJAX
----------------------------------------------------------------
var path='\\uploads\\';
var downloaddatei="beispiel.jpg";
$.ajax({
type:"GET",
url:"proxy/",
accepts:'application/octet-stream',
contentType:'application/octet-stream',
/*** download file ***/
data:{ pfad: path, datei: downloaddatei },
success: function(data, textStatus, jqXHR){
//alert(textStatus);
window.location.href='http://111.111.111.11/proxy/?pfad='+path+'&datei='+downloaddatei;
},
error: function (xhr, textStatus, thrownError){
//alert(thrownError);
},
complete: function(jqXHR){
//alert(jqXHR.statusText);
}
});
_____________________________________________________________
GET REQUEST HEADER
______________________________________________________________
Host 111.111.111.11
User-Agent Mozilla
Accept-Language de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding gzip, deflate
Accept-Charset ISO-8859-1,utf-8;q=0.7,*;q=0.7
Proxy-Connection keep-alive
Content-Type application/octet-stream
X-Requested-With XMLHttpRequest
Referer http://111.111.111.11/
*******************************************************************
Request Resultat:
http://111.111.111.11/proxy/?pfad=%5Cuploads%5C&datei=beispiel.jpg
*******************************************************************
______________________________________________________________
HTTP RESPONSE
______________________________________________________________
Content-Length 777835
Content-Type application/octet-stream
Expires Fri, 12 Aug 2011 16:00:51 GMT
Last-Modified Wed, 17 Aug 2011 12:01:51 GMT
Content-Disposition attachment; filename="beispiel.jpg";
*******************************************************************
Status 200 OK im Antwortbody die Datei als application/octetstream
*******************************************************************
Wenn man jetzt die url komplett von Hand in die Adresszeile kopiert, öffnet sich
der Download-Dialog, nicht aber, wenn man nur http://111.111.111.11/ eingibt.
Via window.location.href kann ich den gewünschten effekt erzielen und das bild runterladen, wenn ich dann
aber die seite per f5 "refreshe", lande ich natürlich auch bei der angegeben window.location - url und da will keiner hin,
nur weil der User eine Datei runterlädt^^ Und: Ich hab ja die request-url von hand eingetragen, auch unschön..
Wer weiß Rat? :-) Danke..
Hi,
ABER ich erwarte eigentlich, dass sich dann ein pop-up-dialog zum speichern der datei öffnet, was es nicht tut.
Natürlich tut es das nicht, weil du mit AJAX explizit einen Request im *Hintergrund* machst.
(ungeachtet der tatache, dass es ungeignet ist dafür, geht es darum einen workaround zu finden, denn AJAX ist wegen authentifizierung "pflicht" :-))
Wenn du schon erkannt hast, das AJAX für dein Vorhaben ungeeignet ist - wieso benutzt du es dann dafür?
Und wegen was für einer Art von Authentifizierung soll AJAX dabei „Pflicht“ sein?
Wenn man jetzt die url komplett von Hand in die Adresszeile kopiert, öffnet sich der Download-Dialog, nicht aber, wenn man nur http://111.111.111.11/ eingibt.
Erstaunt es dich wirklich, dass zwei komplett verschiedene Ressourcen auch ein unterschiedliches Verhalten des Clients auslösen können ...?
MfG ChrisB
lieber chrisB,
Natürlich tut es das nicht, weil du mit AJAX explizit einen Request im *Hintergrund* machst.
genau. und dafür suche ich einen workaround, wie zB mehrfach beschrieben das setzen window.location vorgeschlagen..
Wenn du schon erkannt hast, das AJAX für dein Vorhaben ungeeignet ist - wieso benutzt du es dann dafür?
eine http-header-authentifizierung. serverseitig, darauf habe ich keinen einfluss und ist leider nicht thema meiner frage (sonst würd ichs dem servermenschen überbügeln :-))
Erstaunt es dich wirklich, dass zwei komplett verschiedene Ressourcen auch ein unterschiedliches Verhalten des Clients auslösen können ...?
erstaunt mich nicht. deswegen frage ich nach einem workaround, besseren ideen, ansätzen.
hat jemand konkrete inhaltliche vorschläge oder "sachdienliche hinweise" :-)?
Hi,
Wenn du schon erkannt hast, das AJAX für dein Vorhaben ungeeignet ist - wieso benutzt du es dann dafür?
eine http-header-authentifizierung.
Das beantwortet nicht die Frage, warum du AJAX für dein Vorhaben nutzen willst/wolltest.
Erstaunt es dich wirklich, dass zwei komplett verschiedene Ressourcen auch ein unterschiedliches Verhalten des Clients auslösen können ...?
erstaunt mich nicht.
Und wieso erwähnst du es dann, wenn es mit dem Thema eigentlich gar nichts zu tun hat?
deswegen frage ich nach einem workaround, besseren ideen, ansätzen.
Stinknormaler Link mit target="_blank".
Jeder vernünftige Browser sollte damit derart umgehen können, dass er das damit erzeugte neue Fenster/Tab automatisch wieder schließt, sobald er merkt, dass er als Antwort auf den Request nichts bekommt, was er in einem solchen darstellen könnte, und er stattdessen den Download-Dialog anbieten muss.
MfG ChrisB
Das beantwortet nicht die Frage, warum du AJAX für dein Vorhaben nutzen willst/wolltest.
ich muss für jeden request/jede interaktion mit dem server die authentifizierung per http-auth-header mitsenden. wenn du eine passende umgehung dessen per "stinknormalem link" weißt, freue ich mich :-)
Und wieso erwähnst du es dann, wenn es mit dem Thema eigentlich gar nichts zu tun hat?
das habe ich extra erwähnt, weil ich ahnte, dass es zuallererst antworten geben wird, dass ajax nicht geeignet ist.
Stinknormaler Link mit target="_blank".
Jeder vernünftige Browser sollte damit derart umgehen können, dass er das damit erzeugte neue Fenster/Tab automatisch wieder schließt, sobald er merkt, dass er als Antwort auf den Request nichts bekommt, was er in einem solchen darstellen könnte, und er stattdessen den Download-Dialog anbieten muss.
wie gesagt, das klingt gut. wenn ich dem link dann noch folgen könnte und gleichzeitig dem server wieder die auth. per ajax senden? wenn der server keine authentifizierung bekommt, passiert gor nix.
Moin!
Das beantwortet nicht die Frage, warum du AJAX für dein Vorhaben nutzen willst/wolltest.
ich muss für jeden request/jede interaktion mit dem server die authentifizierung per http-auth-header mitsenden. wenn du eine passende umgehung dessen per "stinknormalem link" weißt, freue ich mich :-)
Es gibt Standardmethoden, wie man das tun kann. Alle sind auch ohne Ajax funktional. Was habt ihr euch ausgedacht, diese Mechanismen nicht zu verwenden?
Mit AJAX geht es jedenfalls nicht. Dein Request schickt dir die gesamte Datei in das Response-Ergebnis, und von dort kriegst du es nicht auf die Festplatte weggeschrieben.
Und wieso erwähnst du es dann, wenn es mit dem Thema eigentlich gar nichts zu tun hat?
das habe ich extra erwähnt, weil ich ahnte, dass es zuallererst antworten geben wird, dass ajax nicht geeignet ist.
Ajax ist nicht geeignet - egal was du da als Authentifizierung zu tun hast. Finde eine Lösung, die dieses Authentifizierungsproblem behebt. Danach kannst du dann auch auf Ajax verzichten. :)
Stinknormaler Link mit target="_blank".
Jeder vernünftige Browser sollte damit derart umgehen können, dass er das damit erzeugte neue Fenster/Tab automatisch wieder schließt, sobald er merkt, dass er als Antwort auf den Request nichts bekommt, was er in einem solchen darstellen könnte, und er stattdessen den Download-Dialog anbieten muss.wie gesagt, das klingt gut. wenn ich dem link dann noch folgen könnte und gleichzeitig dem server wieder die auth. per ajax senden? wenn der server keine authentifizierung bekommt, passiert gor nix.
Klären wir doch zunächst mal, was das für eine Authentifizierung sein soll...
- Sven Rautenberg
hallo sven rautenberg,
Es gibt Standardmethoden, wie man das tun kann. Alle sind auch ohne Ajax funktional. Was habt ihr euch ausgedacht, diese Mechanismen nicht zu verwenden?
hm. der servermensch dachte sich eines schönen tages aus, dass man per login die anmeldedaten für jegliche kommunikation mit dem server via:
beforeSend:function (xhr){ xhr.setRequestHeader('Authorization', 'Basic'+base64encode(userdaten));
}
vollzieht. egal ob ich also einen ordner erstelle, einen upload mache oder etwas umbenenne, schicke ich immer diesen header mit. was auch ich aus sicherheitstechn. gründen gruselig finde, denn man muss sich ja nur aus dem header die daten zurückkodieren und schon...aber das ist es, was fkt. soll.
Mit AJAX geht es jedenfalls nicht. Dein Request schickt dir die gesamte Datei in das Response-Ergebnis, und von dort kriegst du es nicht auf die Festplatte weggeschrieben.
google chrome könnte das als einziges per fileWriter (file api html5), der schreibt sich den blob weg :-) ..
Ajax ist nicht geeignet - egal was du da als Authentifizierung zu tun hast. Finde eine Lösung, die dieses Authentifizierungsproblem behebt. Danach kannst du dann auch auf Ajax verzichten. :)
Klären wir doch zunächst mal, was das für eine Authentifizierung sein soll...
dann muss ich doch dem, der das verbrochen hat, den schuh anziehen?
egal ob ich nun einen anchor mit target _blank oder ein input hidden einsetze: wenn ich ohne authentifizierungsheader auf jedwede url mit params zugreifen will, bekomme ich eine 401^^
Hi,
hm. der servermensch dachte sich eines schönen tages aus, dass man per login die anmeldedaten für jegliche kommunikation mit dem server via:
beforeSend:function (xhr){ xhr.setRequestHeader('Authorization', 'Basic'+base64encode(userdaten));
}
> vollzieht. egal ob ich also einen ordner erstelle, einen upload mache oder etwas umbenenne, schicke ich immer diesen header mit. was auch ich aus sicherheitstechn. gründen gruselig finde, denn man muss sich ja nur aus dem header die daten zurückkodieren und schon...aber das ist es, was fkt. soll.
Dann mach dem Servermensch bitte klar, was für ein Nonsense das ist - die Zugangsdaten zum Client zu übermitteln, nur um sie sich dann von diesem zurück schicken zu lassen.
Das bietet in der Form \*überhaupt\* \*keine\* Sicherheit, und kann ersatzlos entfallen.
> dann muss ich doch dem, der das verbrochen hat, den schuh anziehen?
Nein, ausziehen. Und dann damit verprügeln.
> egal ob ich nun einen anchor mit target \_blank oder ein input hidden einsetze: wenn ich ohne authentifizierungsheader auf jedwede url mit params zugreifen will, bekomme ich eine 401^^
Noch mal: Wenn der Browser sich bereits mit einen Request erfolgreich authentifiziert hat - dann \*merkt\* er sich diese Daten, und schickst sie beim nächsten Request nach einer Ressource automatisch wieder mit.
Du könntest also zunächst einen AJAX-Request auf irgendeine „uninteressante“ Ressource im Realm absetzen, dabei die Zugangsdaten mitgeben (nicht über einen selbstgebastelten Header, sondern über die dafür vorgesehenen Parameter) - und dann sollte der Browser beim anschließenden Ausführen des stinknormalen Links nicht (erneut) nachfragen.
Ist und bleibt hinsichtlich „Sicherheit“ natürlich trotzdem kolossaler Blödsinn.
MfG ChrisB
--
RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
Noch mal: Wenn der Browser sich bereits mit einen Request erfolgreich authentifiziert hat - dann *merkt* er sich diese Daten, und schickst sie beim nächsten Request nach einer Ressource automatisch wieder mit.
Du könntest also zunächst einen AJAX-Request auf irgendeine „uninteressante“ Ressource im Realm absetzen, dabei die Zugangsdaten mitgeben (nicht über einen selbstgebastelten Header, sondern über die dafür vorgesehenen Parameter) - und dann sollte der Browser beim anschließenden Ausführen des stinknormalen Links nicht (erneut) nachfragen.
Ist und bleibt hinsichtlich „Sicherheit“ natürlich trotzdem kolossaler Blödsinn.
okay, danke! das hat mir geholfen, was ich nicht wusste, ist, dass die auth. nur "einmal stattfinden" muss und sich der browser diese dann merken sollte. vielleicht hab ichs am anfang auch zu umständlich erklärt. ich probiere das morgen aus und sag noch mal was rausgekommen ist (auch beim verprügeln :-))
Moin!
Noch mal: Wenn der Browser sich bereits mit einen Request erfolgreich authentifiziert hat - dann *merkt* er sich diese Daten, und schickst sie beim nächsten Request nach einer Ressource automatisch wieder mit.
Du könntest also zunächst einen AJAX-Request auf irgendeine „uninteressante“ Ressource im Realm absetzen, dabei die Zugangsdaten mitgeben (nicht über einen selbstgebastelten Header, sondern über die dafür vorgesehenen Parameter) - und dann sollte der Browser beim anschließenden Ausführen des stinknormalen Links nicht (erneut) nachfragen.
Ist und bleibt hinsichtlich „Sicherheit“ natürlich trotzdem kolossaler Blödsinn.
Ich hätte so meine Zweifel, dass man mit Ajax-Requests eine HTTP-basierte Authentifizierung so hinkriegt, dass der Browser sich die Credentials merkt. Ich würde behaupten, dass dafür wenigstens einmal das Standard-Passwort-Feld ausgefüllt werden muss. Danach allerdings werden die Credentials dann für jede Ressource im entsprechenden Realm verwendet, auch bei Ajax.
Das wiederum könnte im Widerspruch zum Wunsch stehen, beim Login auf eben diesen Standard-Passwort-Dialog zu verzichten und lieber ein beliebig stylebares Formular zu nehmen. In solchem Fall ist die korrekte Antwort auf die Authentifizierungsproblematik allerdings cookiebasierte "Session" und nicht selbstgestricktes dauerhaftes Senden des Passworts mit Ajax.
Das Fehlen von HTTPS beweist aber ja sowieso, dass es hier nicht um sicherheitsrelevante Informationen geht. Also kann man sich entsprechende Bemühungen sowieso sparen, sprich: Jeglicher Aufwand zur Verschleierung der Login-Authentifizierung ist sinnlos, weil sowieso im Klartext nachvollziehbar ist, welche Technologie und welche Verfahren zum Einsatz kommen.
Und selbst wenn nicht: Sich ein korrekt funktionierendes Krypto-Verfahren auszudenken ist absolut nicht trivial und sollte nur von erfahrenen Kryptologen in Angriff genommen werden. Otto-Normalprogrammierer bedient sich besser eines der bekannten und als sicher erachteten Verfahren - ansonsten passiert sowas...
- Sven Rautenberg
Hi,
Ich hätte so meine Zweifel, dass man mit Ajax-Requests eine HTTP-basierte Authentifizierung so hinkriegt, dass der Browser sich die Credentials merkt.
Hab's mal eben getestet - und bis auf Opera spielen auch alle Browser mit :-/
MfG ChrisB
Hi,
Das beantwortet nicht die Frage, warum du AJAX für dein Vorhaben nutzen willst/wolltest.
ich muss für jeden request/jede interaktion mit dem server die authentifizierung per http-auth-header mitsenden.
Das macht der Browser, nachdem die Zugangsdaten einmal vom Nutzer eingegeben wurden, für alle Ressourcen innerhalb des gleichen Realm doch automatisch.
MfG ChrisB
Das macht der Browser, nachdem die Zugangsdaten einmal vom Nutzer eingegeben wurden, für alle Ressourcen innerhalb des gleichen Realm doch automatisch.
das wäre ja des rätsels lösung, wenn er das täte. .. was kann es denn für gründe geben, wenn er das nicht tut und man ohne jedes mal wieder den header mitzuschicken bei zugriff ohne den header eine 401 zurück gibt? klingt nach einem guten weg .. :-)!!
Hi!
Stinknormaler Link mit target="_blank".
Jeder vernünftige Browser sollte damit derart umgehen können, dass er das damit erzeugte neue Fenster/Tab automatisch wieder schließt, sobald er merkt, dass er als Antwort auf den Request nichts bekommt, was er in einem solchen darstellen könnte, und er stattdessen den Download-Dialog anbieten muss.
Warum dann überhaupt ein Fenster aufmachen (lassen)? Da flackert nur unnötig der Bildschirm, wenn das gleich wieder geschlossen wird. Und am Verhalten in Richtung Server bringt das neue Fenster keinerlei Änderung.
Lo!
ABER ich erwarte eigentlich, dass sich dann ein pop-up-dialog zum speichern der
datei öffnet, was es nicht tut.
Die Response landet im DOM und das kann mit octet-stream nicht viel anfangen.
Du könntest mit Javascript jedoch ein neues Fensterchen erzeugen, von dort aus den Request senden und mit der Response den kompletten Inhalt überschreiben. Dann sollte auch der Dialog zum Speichern unter kommen (ungetestet).
hallo hotti,
Du könntest mit Javascript jedoch ein neues Fensterchen erzeugen, von dort aus den Request senden und mit der Response den kompletten Inhalt überschreiben. Dann sollte auch der Dialog zum Speichern unter kommen (ungetestet).
ah..könnte so aussehen?
var newWindow = window.open(URL, data, Optionen);
//müsste dann http://111.111.111.11/proxy/?pfad=xyz&datei=beispiel.jpg geben
newWindow=document.open();
//und dann den Dialog abwarten(?)
newWindow.document.close();
probiere ich morgen aus und gebe rückmeldung :-)
danke erstmal