Aktivieren Sie die Zugriffssteuerung auf einem einfachen HTTP-Server

121

Ich habe das folgende Shell-Skript für einen sehr einfachen HTTP-Server:

#!/bin/sh

echo "Serving at http://localhost:3000"
python -m SimpleHTTPServer 3000

Ich habe mich gefragt, wie ich einen CORS-Header wie Access-Control-Allow-Origin: *diesen Server aktivieren oder hinzufügen kann.

MChan
quelle

Antworten:

197

Leider ist der einfache HTTP-Server wirklich so einfach, dass er keine Anpassung zulässt, insbesondere nicht für die von ihm gesendeten Header. Sie können jedoch mit den meisten selbst einen einfachen HTTP-Server erstellen SimpleHTTPRequestHandlerund einfach den gewünschten Header hinzufügen.

Erstellen Sie dazu einfach eine Datei simple-cors-http-server.py(oder was auch immer) und fügen Sie je nach verwendeter Python-Version einen der folgenden Codes ein.

Dann können Sie dies tun python simple-cors-http-server.pyund Ihr geänderter Server wird gestartet, wodurch der CORS-Header für jede Antwort festgelegt wird.

Machen Sie die Datei mit dem Shebang oben ausführbar und fügen Sie sie in Ihren PATH ein. Sie können sie auch einfach mit ausführen simple-cors-http-server.py.

Python 3-Lösung

Python 3 verwendet SimpleHTTPRequestHandlerund HTTPServervom http.serverModul , um den Server auszuführen:

#!/usr/bin/env python3
from http.server import HTTPServer, SimpleHTTPRequestHandler, test
import sys

class CORSRequestHandler (SimpleHTTPRequestHandler):
    def end_headers (self):
        self.send_header('Access-Control-Allow-Origin', '*')
        SimpleHTTPRequestHandler.end_headers(self)

if __name__ == '__main__':
    test(CORSRequestHandler, HTTPServer, port=int(sys.argv[1]) if len(sys.argv) > 1 else 8000)

Python 2-Lösung

Python 2 verwendet SimpleHTTPServer.SimpleHTTPRequestHandlerund das BaseHTTPServerModul , um den Server auszuführen.

#!/usr/bin/env python2
from SimpleHTTPServer import SimpleHTTPRequestHandler
import BaseHTTPServer

class CORSRequestHandler (SimpleHTTPRequestHandler):
    def end_headers (self):
        self.send_header('Access-Control-Allow-Origin', '*')
        SimpleHTTPRequestHandler.end_headers(self)

if __name__ == '__main__':
    BaseHTTPServer.test(CORSRequestHandler, BaseHTTPServer.HTTPServer)

Python 2 & 3 Lösung

Wenn Sie Kompatibilität für Python 3 und Python 2 benötigen, können Sie dieses polyglotte Skript verwenden, das in beiden Versionen funktioniert. Es wird zunächst versucht, von den Python 3-Speicherorten zu importieren, andernfalls wird auf Python 2 zurückgegriffen:

#!/usr/bin/env python
try:
    # Python 3
    from http.server import HTTPServer, SimpleHTTPRequestHandler, test as test_orig
    import sys
    def test (*args):
        test_orig(*args, port=int(sys.argv[1]) if len(sys.argv) > 1 else 8000)
except ImportError: # Python 2
    from BaseHTTPServer import HTTPServer, test
    from SimpleHTTPServer import SimpleHTTPRequestHandler

class CORSRequestHandler (SimpleHTTPRequestHandler):
    def end_headers (self):
        self.send_header('Access-Control-Allow-Origin', '*')
        SimpleHTTPRequestHandler.end_headers(self)

if __name__ == '__main__':
    test(CORSRequestHandler, HTTPServer)
Sack
quelle
Ich habe die Anweisungen befolgt, aber durch Ausführen von python simple-cors-http-server.py erhalte ich die folgende Fehlermeldung: python: Datei 'simple-cors-http-server.py' kann nicht geöffnet werden: [Errno 2] Keine solche Datei- oder Verzeichnisabmeldung .... irgendwelche Gedanken?
MChan
4
@poke Der Server antwortet mit der Methode 501 Unsupported ('OPTIONS'). Ich verwende OS X 10.10.1 mit Python 2.7.6. Irgendwelche Vorschläge? HTTP/1.0 501 Unsupported method ('OPTIONS') Server: SimpleHTTP/0.6 Python/2.7.6 Date: Wed, 21 Jan 2015 23:16:10 GMT Content-Type: text/html Connection: close Access-Control-Allow-Origin: *
HairOfTheDog
1
@HairOfTheDog Der SimpleHTTPRequestHandler unterstützt die HTTP-Methode OPTIONS nicht. Sie können es hinzufügen, wenn Sie möchten (lesen Sie das Python-Handbuch zu HTTP-Servern). oder Sie könnten einfach nicht versuchen, so auf den Server zuzugreifen.
stupsen
2
@RobertoFranceschini Möglicherweise werden Preflight-Anforderungen ausgeführt, für die eine OPTIONSordnungsgemäße Implementierung der Methode erforderlich ist. Bei einfachen Anfragen sollte die Lösung, nur den Access-Control-Allow-OriginHeader zu senden, weiterhin einwandfrei funktionieren.
Poke
1
@ Tyguy7 Dies könnte jedoch ein allgemeines Verhalten mit dem einfachen HTTP-Server sein. Ich hatte zuvor unterschiedliche Ergebnisse in Bezug auf die Leistung. Aber um einen Server für einen Moment einfach laufen zu lassen, halte ich ihn immer noch für die schnellste Lösung.
stupsen
107

Versuchen Sie eine Alternative wie http-Server

Da SimpleHTTPServer nicht wirklich die Art von Server ist, die Sie für die Produktion bereitstellen, gehe ich hier davon aus, dass es Ihnen nicht so wichtig ist, welches Tool Sie verwenden, solange es die Aufgabe erfüllt, Ihre Dateien http://localhost:3000mit CORS-Headern in einer einfachen Version verfügbar zu machen Befehlszeile

# install (it requires nodejs/npm)
npm install http-server -g

#run
http-server -p 3000 --cors

Benötigen Sie HTTPS?

Wenn Sie https in lokal benötigen, können Sie auch Caddy oder Certbot ausprobieren


Einige verwandte Tools, die Sie möglicherweise nützlich finden

  • ngrok : Beim Ausführen ngrok http 3000wird eine URL erstellt https://$random.ngrok.com, mit der jeder auf Ihren http://localhost:3000Server zugreifen kann. Es kann der Welt zeigen, was lokal auf Ihrem Computer ausgeführt wird (einschließlich lokaler Backends / APIs).

  • localtunnel : fast das gleiche wie ngrok

  • Jetzt : Beim Ausführen nowwerden Ihre statischen Assets online hochgeladen und dort bereitgestellt https://$random.now.sh. Sie bleiben für immer online, sofern Sie nichts anderes entscheiden. Die Bereitstellung ist dank unterschiedlicher Einstellungen schnell (mit Ausnahme der ersten). Jetzt ist es für die Bereitstellung von Produktions-Frontend- / SPA-Code geeignet. Es können auch Docker- und NodeJS-Apps bereitgestellt werden. Es ist nicht wirklich kostenlos, aber sie haben einen kostenlosen Plan.

Sebastien Lorber
quelle
4
Ich bin ein einfacher Mann. Ich sehe eine Lösung, die die Installation npmauf einem Computer erfordert, von dem nur bekannt ist, dass pythonich sie habe.
Parthian Shot
6
@ParthianShot: Vielleicht möchten Sie lernen, das beste Werkzeug für den Job zu verwenden.
Dan Dascalescu
2
@ParthianShot Viele Entwickler haben bereits node / npm installiert. Der Fragentitel ist allgemein genug, um eine große Zielgruppe von Benutzern anzusprechen, die sich eindeutig nicht für Python oder SimpleHTTPServer interessieren, was durch Upvotes bestätigt wird. Es ist nicht, weil es für Sie nicht hilfreich ist, dass es für alle ist. Es gibt gute Gründe, Node und Python nicht zu mögen. Dinge wie Leftpad / Bad Publish / Bad Git-Nutzung scheinen mir völlig unabhängig zu sein.
Sebastien Lorber
5
Das Hinzufügen einer zusätzlichen Sprache und eines zusätzlichen Frameworks verursacht technische Schulden und erhöht die Angriffsfläche einer Umgebung. "Schwerwiegende Fehler können in jeder Programmiersprache gemacht werden" Stimmt, aber JS macht dies einfacher als die meisten anderen Sprachen. Und jede Sprache hat Fallstricke; Je weniger Sprachen Sie verwenden, desto weniger wahrscheinlich ist es, dass ein Entwickler, der mit einer der Sprachen nicht vertraut ist, einen Fehler macht, der in einer anderen Sprache kein Fehler wäre.
Parthian Shot
2
Dies ist wie die Adoption eines Kindes jedes Mal, wenn Sie Hilfe im Haus benötigen. es schafft mehr Probleme als es die Straße hinunter löst.
Parthian Shot
1

Ich hatte das gleiche Problem und kam zu dieser Lösung:

class Handler(SimpleHTTPRequestHandler):
    def send_response(self, *args, **kwargs):
        SimpleHTTPRequestHandler.send_response(self, *args, **kwargs)
        self.send_header('Access-Control-Allow-Origin', '*')

Ich habe einfach eine neue Klasse erstellt, die von SimpleHTTPRequestHandler erbt und nur die send_responseMethode ändert .

Hugo Trentesaux
quelle
0

Sie müssen Ihre eigenen Instanzen von do_GET () (und do_HEAD () bereitstellen, wenn Sie HEAD-Operationen unterstützen möchten). etwas wie das:

class MyHTTPServer(SimpleHTTPServer):

    allowed_hosts = (('127.0.0.1', 80),)

    def do_GET(self):
        if self.client_address not in allowed_hosts:
            self.send_response(401, 'request not allowed')
        else:
            super(MyHTTPServer, self).do_Get()
user590028
quelle
Vielen Dank für Ihre Antwort, aber ich habe keinerlei Python-Kenntnisse. Ich verwende nur das oben erwähnte Shell-Skript als einfachen http-Server für meine Emberjs-Apps. Erst als ich mit dem Zugriffskontrollproblem kollidierte, stellte ich fest, dass ich es auf diesem einfachen http-Server aktivieren muss. Nach einigen Recherchen habe ich hinzugefügt ('CrossOrigin' aktivieren, Ursprünge => '*';), aber es ist nicht überraschend, dass es nicht funktioniert hat. Wenn Sie mich auf ein einfaches Python-HTTP-Server-Shell-Skript verweisen können, das die Zugriffssteuerungsfunktion enthält, die sehr geschätzt wird
MChan
Nebenbei bemerkt, ich versuche hier nicht wirklich faul zu sein, aber fange an, Python zu lernen, nur um diese Funktion zum simpleHTTP-Server hinzuzufügen. Das klingt zu diesem Zeitpunkt nicht logisch, also hatte ich gehofft, dass es einfach hinzuzufügen ist oder hoffentlich finde ich es Ein alternatives / fertiges Python-Skript, das die Arbeit erledigen kann, damit ich meine
Entwicklungsarbeit
3
Der SimpleHTTPServer bietet keine Optionen zur Unterstützung der Zugriffssteuerung. Entweder müssen Sie Ihren eigenen Code rollen - oder Sie müssen zu einem anderen Webserver wechseln, der Zugriffskontrollen unterstützt. Denken Sie an lighttpd.net
user590028