Abilita il controllo degli accessi su un semplice server HTTP


121

Ho il seguente script di shell per un server HTTP molto semplice:

#!/bin/sh

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

Mi chiedevo come posso abilitare o aggiungere un'intestazione CORS come Access-Control-Allow-Origin: *questo server?

Risposte:


197

Sfortunatamente, il semplice server HTTP è davvero così semplice da non consentire alcuna personalizzazione, soprattutto non per le intestazioni che invia. È tuttavia possibile creare un semplice server HTTP da soli, utilizzando la maggior parte di SimpleHTTPRequestHandlere aggiungere semplicemente l'intestazione desiderata.

Per questo, crea semplicemente un file simple-cors-http-server.py(o qualsiasi altra cosa) e, a seconda della versione di Python che stai utilizzando, inserisci uno dei seguenti codici all'interno.

Quindi puoi farlo python simple-cors-http-server.pye lancerà il tuo server modificato che imposterà l'intestazione CORS per ogni risposta.

Con lo shebang in alto, rendi il file eseguibile e mettilo nel tuo PERCORSO, e puoi semplicemente eseguirlo usando simple-cors-http-server.pyanche tu .

Soluzione Python 3

Python 3 utilizza SimpleHTTPRequestHandlere HTTPServerdal http.servermodulo per eseguire il server:

#!/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)

Soluzione Python 2

Python 2 utilizza SimpleHTTPServer.SimpleHTTPRequestHandlere il BaseHTTPServermodulo per eseguire il server.

#!/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)

Soluzione Python 2 e 3

Se hai bisogno di compatibilità sia per Python 3 che per Python 2, puoi usare questo script poliglotta che funziona in entrambe le versioni. Prima tenta di importare dalle posizioni di Python 3, altrimenti torna a Python 2:

#!/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)

Ho seguito le istruzioni ma eseguendo python simple-cors-http-server.py ottengo l'errore: python: impossibile aprire il file 'simple-cors-http-server.py': [Errno 2] Nessun file o logout di directory di questo tipo ....qualche idea?
MChan

4
@poke Il server risponde con il metodo 501 Unsupported ("OPTIONS"). Utilizzo OS X 10.10.1 con Python 2.7.6. Eventuali suggerimenti? 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 SimpleHTTPRequestHandler non supporta il metodo HTTP OPTIONS. Puoi aggiungerlo se vuoi (leggi il manuale di Python sui server HTTP); oppure potresti semplicemente non provare ad accedere al server in quel modo.
colpisci il

2
@RobertoFranceschini Potresti incappare in richieste di preflight che richiedono l' OPTIONSimplementazione corretta del metodo. Per quanto riguarda le richieste semplici, la soluzione di inviare solo l' Access-Control-Allow-Originintestazione dovrebbe comunque funzionare bene.
colpisci il

1
@ Tyguy7 Questo potrebbe essere un comportamento generale con il semplice server HTTP. Ho avuto risultati diversi in merito alle prestazioni prima. Ma per eseguire semplicemente un server per un momento, lo considero ancora la soluzione più rapida.
colpisci

108

Prova un'alternativa come http-server

Poiché SimpleHTTPServer non è proprio il tipo di server che distribuisci in produzione, presumo qui che non ti interessi più di tanto quale strumento usi fintanto che svolge il compito di esporre i tuoi file http://localhost:3000con intestazioni CORS in un semplice riga di comando

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

#run
http-server -p 3000 --cors

Hai bisogno di HTTPS?

Se hai bisogno di https in locale puoi anche provare caddy o certbot


Alcuni strumenti correlati che potresti trovare utili

  • ngrok : durante l'esecuzione ngrok http 3000, crea un URL https://$random.ngrok.comche consente a chiunque di accedere al tuo http://localhost:3000server. Può esporre al mondo ciò che viene eseguito localmente sul tuo computer (inclusi backend / API locali)

  • localtunnel : quasi uguale a ngrok

  • ora : durante l'esecuzione now, carica le risorse statiche online e le distribuisce in https://$random.now.sh. Rimangono online per sempre a meno che tu non decida diversamente. L'implementazione è veloce (tranne il primo) grazie a diffing. Ora è adatto per la distribuzione di codice frontend / SPA di produzione Può anche distribuire app Docker e NodeJS. Non è veramente gratuito, ma hanno un piano gratuito.


5
Sono un uomo semplice. Vedo una soluzione che richiede l'installazione npmsu una macchina che è nota solo per avere python, ho downvote.
Parthian Shot

6
@ParthianShot: potresti voler imparare a usare lo strumento migliore per il lavoro.
Dan Dascalescu

2
@ParthianShot Molti sviluppatori hanno già installato node / npm. E il titolo della domanda è abbastanza generico da attirare un vasto pubblico di utenti che chiaramente non si preoccupano di python o SimpleHTTPServer, il che è confermato dai voti positivi. Non è perché non ti è utile che lo sia per tutti. Ci sono buone ragioni per non apprezzare sia Node che Python. Cose come leftpad / cattiva pubblicazione / cattivo utilizzo di git mi sembrano totalmente estranei.
Sebastien Lorber

5
L'aggiunta di un linguaggio e di un framework aggiuntivi comporta un debito tecnico e aumenta la superficie di attacco di un ambiente. "È possibile commettere errori fatali in qualsiasi linguaggio di programmazione" Vero, ma JS rende questo modo più semplice rispetto alla maggior parte degli altri linguaggi. E ogni lingua ha dei trucchi; meno lingue usi, meno è probabile che uno sviluppatore che non ha familiarità con una delle lingue commetta un errore che non sarebbe un errore in un'altra lingua.
Parthian Shot

2
È come adottare un bambino ogni volta che hai bisogno di aiuto in casa; crea più problemi di quanti ne risolva lungo la strada.
Parthian Shot

1

Ho avuto lo stesso problema e sono arrivato a questa soluzione:

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

Ho semplicemente creato una nuova classe ereditando da SimpleHTTPRequestHandler che cambia solo il send_responsemetodo.


0

Dovrai fornire le tue istanze di do_GET () (e do_HEAD () se scegli di supportare le operazioni HEAD). qualcosa come questo:

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()

Grazie per la tua risposta, ma non ho alcuna conoscenza di Python, sto solo usando lo script di shell menzionato sopra come un semplice server http per le mie app Emberjs. Solo quando sono entrato in conflitto con il problema del controllo degli accessi, ho cercato di scoprire che dovevo abilitarlo in questo semplice server http. Quindi dopo alcune ricerche ho aggiunto (abilita 'CrossOrigin', origins => '*';) ma non sorprende che non abbia funzionato. Se puoi indicarmi qualsiasi semplice script di shell del server http Python che includa la funzione di controllo degli accessi che sarà molto apprezzata
MChan

In una nota minore, non sto cercando di essere pigro qui davvero, ma iniziare a imparare Python solo per aggiungere questa funzionalità al semplice server HTTP non suona logico a questo punto, quindi speravo che fosse facile aggiungere O spero di poterlo trovare uno script Python alternativo / già pronto che può fare il lavoro in modo che io possa continuare con il mio lavoro di sviluppo
MChan

3
Il SimpleHTTPServer non ha opzioni per supportare i controlli di accesso. O dovrai eseguire il roll del tuo codice o passare a un altro server web che supporti i controlli di accesso. Pensa a lighttpd.net
user590028
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.