2017-03-04 4 views
2

In meiner Apache-Web-Server-Konfiguration ignoriert, ich Unterstützung für zwei Header hinzufügen, die nicht Teil des Standard sechs sind:Access-Control-Expose-Header Einstellung

Header set Access-Control-Allow-Origin "*" 
Header set Access-Control-Expose-Headers: Content-Disposition,X-Filename 

Meine Datei exportieren CGI-Skript druckt Header-Daten enthalten, für diese beiden Felder, zB:

... 
print "Content-Disposition: attachment; filename=%s\n" % (out_fn) 
print "X-Filename: %s\n" % (out_fn) 
... 

Mein clientseitige AJAX-Aufruf den Wert von Content-Disposition auf eine erfolgreiche AJAX-Anforderung abzurufen versucht:

var export_form = new FormData(); 
export_form.append("settings", JSON.stringify(settings)); 
export_form.append("format", format); 
$.ajax({ 
    url: "services/export_data.py", 
    type: "POST", 
    async: true, 
    cache: false, 
    data: export_form, 
    processData: false, 
    contentType: false, 
    success: function(response, textStatus, jqXHR) { 
     console.log("success"); 
     console.log(jqXHR.getAllResponseHeaders()); 
     console.log(jqXHR.getResponseHeader('Content-Disposition')); 
    }, 
    error: function(jqXHR, textStatus, errorThrown) { 
     console.log("export_form submit failed:", jqXHR.status, jqXHR.statusText); 
     console.log(jqXHR); 
    } 
}); 

Meine Test-Anforderungen auf der Client-Seite vollständig und führen Sie den success Rückruf, und ich erhalte die Dateidaten wieder im response Feld, aber ich bekomme null für den Antwort-Header Content-Disposition.

Mit anderen Worten, ein Probenergebnis von console.log(jqXHR.getAllResponseHeaders()) ist:

Date: Sat, 04 Mar 2017 19:42:27 GMT 
Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.1e-fips mod_python/3.5.0- Python/2.7.5 mod_perl/2.0.10 Perl/v5.16.3 
Transfer-Encoding: chunked 
Content-Type: application/pdf 
Access-Control-Allow-Origin: * 
Access-Control-Expose-Headers: Content-Disposition,X-Filename 
Connection: Keep-Alive 
Keep-Alive: timeout=5, max=100 

Während das Ergebnis console.log(jqXHR.getResponseHeader('Content-Disposition')) leer ist:

null 

Warum ist meine AJAX-Anforderung nicht in der Lage, den Wert von Content-Disposition abrufen , wenn ich es explizit über die Webserver-Konfiguration verfügbar gemacht habe, und ich habe es richtig in der Antwort eingestellt?


Um Probleme mit Zeilenumbrüchen Adresse, benutzte ich sys.stdout.write mehr Kontrolle über die Ausgabe zu erhalten, zum Beispiel:

sys.stdout.write("Content-Type: %s\n" % (mime_type)) 
sys.stdout.write("Content-Disposition: attachment; filename=%s\n" % (output_fn)) 
sys.stdout.write("X-Filename: %s\n" % (output_fn)) 
sys.stdout.write("Content-Description: File to download\n\n") 
with open(out_fn, "rb") as out_fh: 
    sys.stdout.write(out_fh.read()) 

Leider sind diese beiden Header waren noch nicht sichtbar für die AJAX-Antwort über console.log(jqXHR.getResponseHeader('Content-Disposition')) und console.log(jqXHR.getResponseHeader('X-Filename')) , die beide null waren.

+0

Sind die Header enthielten tatsächlich in der Antwort (können Sie sie in Ihrem Browser-Entwickler-Konsole sehen)? – Bewusstsein

+0

@AlexReynolds Wenn Sie Python 'print' verwenden, müssen Sie kein neues Zeilenumbruchzeichen hinzufügen, weil das' print' das tatsächlich hinzufügt. Sind Sie sicher, dass das Modul "mod_headers" aktiviert ist? Es funktioniert tadellos auf mir ohne neue Zeichensatzzeichenfolgenbeendigung, wenn ich den AJAX Anruf von einer anderen Domäne tue und es die Überschriften zurückgibt. Bitte werfen Sie einen Blick auf den Screenshot hier: http://zikro.gr/dbg/srv/apache-custom-cors-headers--1.png. Ich kann Ihnen keinen Link geben, weil ich den Apache-Server auf einer virtuellen Maschine laufen lasse, aber ich kann sie zur Verfügung stellen, wenn Sie sie sehen wollen. –

+0

Ich habe meine VM mit Apache 2.4 mit einem funktionierenden Beispiel geöffnet. Sie können das Arbeitsskript mit Ihrem AJAX-Aufruf hier versuchen http://zikro.gr/dbg/srv/apache-headers/, und wenn Sie die Quelle überprüfen, sehen Sie, dass die URL auf einem anderen Server ist. Sowohl 'print' als auch' sys.stdout.write' funktionieren und geben die Header im Konsolenfenster aus. Sehen Sie den Konsolen-Screenshot hier http://zikro.gr/dbg/srv/apache-custom-cors-headers-2.png. Haben Sie die Protokolldateien auf mögliche Fehler überprüft? Ruft der AJAX-Aufruf "200 Success" zurück? –

Antwort

0

Access-Control-Expose-Headers gilt nur für CORS-Anfragen: Content-Disposition und X-Filename in Ihrem Fall werden zu den sechs Standard-Headern hinzugefügt, die eine andere Domäne sehen darf, wenn sie Daten von Ihrem Server anfordert.

Die Anfrage Sie senden sieht nicht aus wie es Quer Herkunft ist, aber: die URL services/export_data.py verweist nicht auf eine andere Domain und die Ausgabe von console.log(jqXHR.getAllResponseHeaders()) enthält Header wie Server oder Date, die nicht in die sechs sind Standard und zwei freiliegende Header.


Ich denke, Ihr Problem Server-Seite ist, nicht mit dem Javascript, und dass Sie nicht tatsächlich die beiden Header Senden Sie einschließen möchten.

Das CGI-Skript scheint in Python (basierend auf der Dateierweiterung in der URL) geschrieben zu werden. Wenn dies der Fall ist, druckt print "\n" tatsächlich zwei Zeilenumbrüche, und da eine leere Zeile Header und Daten in HTTP begrenzt, werden die beiden Header, die Sie hinzufügen, in die HTTP-Antwort eingeschlossen, aber als Daten und nicht als Header behandelt. Gibt es eine print Aussage, bevor Sie die Content-Disposition hinzufügen? Das würde erklären, warum das auch nicht als Überschrift erscheint.

Um dies zu lösen einfach die hinteren \n in Ihrem Skript entfernen:

... 
print "Content-Disposition: attachment; filename=%s" % (out_fn) 
print "X-Filename: %s" % (out_fn) 
...