Aktifkan kontrol akses pada server HTTP sederhana

121

Saya memiliki skrip shell berikut untuk server HTTP yang sangat sederhana:

#!/bin/sh

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

Saya bertanya-tanya bagaimana saya dapat mengaktifkan atau menambahkan header CORS seperti Access-Control-Allow-Origin: *ke server ini?

MChan
sumber

Jawaban:

197

Sayangnya, server HTTP sederhana benar-benar sesederhana itu sehingga tidak memungkinkan penyesuaian apa pun, terutama untuk header yang dikirimnya. Namun Anda dapat membuat server HTTP sederhana sendiri, menggunakan sebagian besar SimpleHTTPRequestHandler, dan cukup menambahkan header yang diinginkan.

Untuk itu, cukup buat file simple-cors-http-server.py(atau apa pun) dan, tergantung pada versi Python yang Anda gunakan, masukkan salah satu kode berikut ke dalamnya.

Kemudian Anda bisa melakukannya python simple-cors-http-server.pydan itu akan meluncurkan server Anda yang dimodifikasi yang akan mengatur header CORS untuk setiap respons.

Dengan shebang di bagian atas, buat file tersebut dapat dieksekusi dan masukkan ke PATH Anda, dan Anda juga dapat menjalankannya menggunakan simple-cors-http-server.py.

Solusi Python 3

Python 3 menggunakan SimpleHTTPRequestHandlerdan HTTPServerdari http.servermodul untuk menjalankan 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)

Solusi Python 2

Python 2 menggunakan SimpleHTTPServer.SimpleHTTPRequestHandlerdan BaseHTTPServermodul untuk menjalankan 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)

Solusi Python 2 & 3

Jika Anda memerlukan kompatibilitas untuk Python 3 dan Python 2, Anda dapat menggunakan skrip polyglot yang berfungsi di kedua versi ini. Pertama kali mencoba untuk mengimpor dari lokasi Python 3, dan sebaliknya kembali ke 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)
menyodok
sumber
Saya mengikuti instruksi tetapi dengan menjalankan python simple-cors-http-server.py Saya mendapatkan kesalahan: python: tidak dapat membuka file 'simple-cors-http-server.py': [Errno 2] Tidak ada file atau direktori keluar logout .... ada pemikiran?
MChan
4
@poke Server merespon dengan metode 501 Tidak Didukung ('OPTIONS'). Saya menjalankan OS X 10.10.1 dengan Python 2.7.6. Ada saran? 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 tidak mendukung metode HTTP OPTIONS. Anda dapat menambahkannya jika Anda mau (baca manual Python tentang server HTTP); atau Anda tidak dapat mencoba mengakses server seperti itu.
colek
2
@RobertoFranceschini Anda mungkin mengalami permintaan preflighted yang membutuhkan OPTIONSmetode untuk diterapkan dengan benar. Adapun permintaan sederhana, solusi hanya mengirimkan Access-Control-Allow-Originheader harus tetap berfungsi dengan baik.
aduk
1
@ Tyguy7 Itu mungkin merupakan perilaku umum dengan server HTTP sederhana. Saya memiliki hasil yang berbeda-beda mengenai kinerja sebelumnya. Tetapi untuk sekadar menjalankan server sejenak, saya masih menganggapnya sebagai solusi tercepat.
aduk
108

Coba alternatif seperti http-server

Karena SimpleHTTPServer sebenarnya bukan jenis server yang Anda gunakan untuk produksi, saya berasumsi di sini bahwa Anda tidak terlalu peduli tentang alat mana yang Anda gunakan selama itu berfungsi untuk mengekspos file Anda http://localhost:3000dengan header CORS secara sederhana. garis komando

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

#run
http-server -p 3000 --cors

Butuh HTTPS?

Jika Anda membutuhkan https di lokal Anda juga dapat mencoba caddy atau certbot


Beberapa alat terkait yang mungkin berguna bagi Anda

  • ngrok : saat dijalankan ngrok http 3000, ini membuat url https://$random.ngrok.comyang mengizinkan siapa pun mengakses http://localhost:3000server Anda . Itu dapat mengekspos ke dunia apa yang berjalan secara lokal di komputer Anda (termasuk backend / apis lokal)

  • localtunnel : hampir sama dengan ngrok

  • now : saat dijalankan now, aset statis Anda diupload secara online dan diterapkan ke https://$random.now.sh. Mereka tetap online selamanya kecuali Anda memutuskan sebaliknya. Deployment cepat (kecuali yang pertama) berkat diffing. Sekarang cocok untuk produksi frontend / penyebaran kode SPA. Ini juga dapat menerapkan aplikasi Docker dan NodeJS. Ini tidak benar-benar gratis, tetapi mereka memiliki paket gratis.

Sebastien Lorber
sumber
5
Saya orang yang sederhana. Saya melihat solusi yang memerlukan penginstalan npmpada mesin yang hanya diketahui memiliki python, saya downvote.
Parthian Shot
6
@ParthianShot: Anda mungkin ingin belajar menggunakan alat terbaik untuk pekerjaan itu.
Dan Dascalescu
2
@ParthianShot Banyak pengembang sudah menginstal node / npm. Dan judul pertanyaannya cukup umum untuk mendorong banyak pengguna yang jelas-jelas tidak peduli dengan python atau SimpleHTTPServer, yang dikonfirmasi oleh suara positif. Bukan karena tidak membantu Anda, tetapi untuk semua orang. Ada alasan bagus untuk tidak menyukai Node dan Python juga. Hal-hal seperti leftpad / publikasi buruk / penggunaan git buruk tampaknya sama sekali tidak ada hubungannya dengan saya.
Sebastien Lorber
5
Menambahkan bahasa dan kerangka kerja tambahan menimbulkan hutang teknis dan meningkatkan permukaan serangan suatu lingkungan. "Kesalahan fatal dapat dibuat dalam bahasa pemrograman apa pun" Benar, tetapi JS membuatnya lebih mudah daripada kebanyakan bahasa lainnya. Dan setiap bahasa memiliki gotcha; semakin sedikit bahasa yang Anda gunakan, semakin kecil kemungkinan beberapa pengembang yang tidak terbiasa dengan salah satu bahasa membuat kesalahan yang tidak akan menjadi kesalahan dalam bahasa lain.
Parthian Shot
2
Ini seperti mengadopsi seorang anak setiap kali Anda membutuhkan bantuan di sekitar rumah; itu menciptakan lebih banyak masalah daripada menyelesaikannya di jalan.
Parthian Shot
1

Saya memiliki masalah yang sama dan sampai pada solusi ini:

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

Saya hanya membuat kelas baru yang mewarisi dari SimpleHTTPRequestHandler yang hanya mengubah send_responsemetode.

Hugo Trentesaux
sumber
0

Anda harus menyediakan contoh do_GET () (dan do_HEAD () Anda sendiri jika memilih untuk mendukung operasi HEAD). sesuatu seperti ini:

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()
pengguna590028
sumber
Terima kasih atas jawaban Anda, tetapi saya tidak memiliki pengetahuan Python apa pun, saya hanya menggunakan skrip shell yang disebutkan di atas sebagai server http sederhana untuk aplikasi Emberjs saya. Hanya ketika bertabrakan dengan masalah kontrol akses, saya meneliti untuk menemukan bahwa saya perlu mengaktifkannya di server http sederhana ini. Jadi setelah beberapa penelitian saya menambahkan (aktifkan 'CrossOrigin', origins => '*';) tetapi tidak mengherankan itu tidak berhasil. Jika Anda dapat mengarahkan saya ke skrip shell server http sederhana Python apa pun yang menyertakan fitur kontrol akses yang akan sangat dihargai
MChan
Pada catatan kecil, saya tidak mencoba untuk malas di sini tapi mulai belajar python hanya untuk menambahkan fitur ini ke server SimpleHTTP kedengarannya tidak logis pada saat ini jadi saya berharap akan mudah untuk menambahkan ATAU semoga saya dapat menemukannya skrip Python alternatif / siap pakai yang dapat melakukan pekerjaan itu sehingga saya dapat melanjutkan pekerjaan pengembang saya
MChan
3
SimpleHTTPServer tidak memiliki opsi untuk mendukung kontrol akses. Entah Anda perlu menggulung kode Anda sendiri - atau beralih ke server web lain yang mendukung kontrol akses. Pikirkan tentang lighttpd.net
user590028