Увімкніть контроль доступу на простому сервері HTTP


121

У мене є такий скрипт оболонки для дуже простого HTTP-сервера:

#!/bin/sh

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

Мені було цікаво, як я можу включити або додати заголовок CORS на зразок Access-Control-Allow-Origin: *цього сервера?

Відповіді:


197

На жаль, простий сервер HTTP насправді настільки простий, що не дозволяє здійснювати будь-які настройки, особливо не для заголовків, які він надсилає. Однак ви можете створити простий сервер HTTP самостійно, використовуючи більшість SimpleHTTPRequestHandler, і просто додати потрібний заголовок.

Для цього просто створіть файл simple-cors-http-server.py(або будь-який інший) і, залежно від версії Python, яку ви використовуєте, покладіть всередину один із наведених нижче кодів.

Тоді ви можете зробити python simple-cors-http-server.pyце, і він запустить ваш змінений сервер, який встановить заголовок CORS для кожної відповіді.

З шебангом вгорі, зробіть файл виконуваним і помістіть його у свій PATH, і ви можете просто запустити його, використовуючи simple-cors-http-server.pyтакож.

Розчин Python 3

Python 3 використовує SimpleHTTPRequestHandlerі HTTPServerз http.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)

Розчин Python 2

Python 2 використовує SimpleHTTPServer.SimpleHTTPRequestHandlerі BaseHTTPServerмодуль для запуску сервера.

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

Якщо вам потрібна сумісність як для Python 3, так і для Python 2, ви можете використовувати цей поліглот-скрипт, який працює в обох версіях. Спочатку він намагається імпортувати з локацій Python 3, а в іншому випадку повертається до 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)

Я дотримувався інструкцій, але виконуючи python simple-cors-http-server.py, я отримую помилку: python: не вдається відкрити файл 'simple-cors-http-server.py': [Errno 2] Немає такого файлу чи виходу з каталогу .... якісь думки?
MChan

4
@poke Сервер реагує методом 501 Непідтримуваний ("ОПЦІЇ"). У мене працює ОС X 10.10.1 з Python 2.7.6. Будь-які пропозиції? 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 не підтримує метод HTTP OPTIONS. Ви можете додати його за бажанням (прочитайте посібник Python про HTTP-сервери); або ви просто не можете намагатися отримати доступ до такого сервера.
ткнути

2
@RobertoFranceschini Можливо, ви зіткнулися з попередньо просвіченими запитами, які вимагають OPTIONSналежного впровадження методу. Що стосується простих запитів, рішення надсилання просто Access-Control-Allow-Originзаголовка все одно має працювати нормально.
ткнути

1
@ Tyguy7 Однак це може бути загальна поведінка з простим сервером HTTP. Я раніше мав різні результати щодо продуктивності. Але для простого запуску сервера на хвилину я все-таки вважаю це швидким рішенням.
ткнути

108

Спробуйте таку альтернативу, як http-сервер

Оскільки SimpleHTTPServer насправді не той тип сервера, який ви розгортаєте у виробництво, я припускаю, що тут вам не дуже важливо, яким інструментом ви користуєтесь, доки це не спрощує розкриття ваших файлів у http://localhost:3000заголовках CORS простим командний рядок

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

#run
http-server -p 3000 --cors

Потрібні HTTPS?

Якщо вам потрібні https в локальному середовищі, ви також можете спробувати Caddy або Certbot


Деякі пов'язані інструменти, які можуть вам бути корисними

  • ngrok : під час запуску ngrok http 3000він створює URL-адресу, https://$random.ngrok.comяка дозволяє будь-кому отримати доступ до вашого http://localhost:3000сервера. Він може відкрити світові те, що працює локально на вашому комп’ютері (включаючи місцеві програмні засоби / apis)

  • localtunnel : майже те саме, що ngrok

  • тепер : під час запуску nowвін завантажує ваші статичні активи в Інтернеті та розгортає їх https://$random.now.sh. Вони залишаються в Інтернеті назавжди, якщо ви не вирішите інше. Розгортання швидке (крім першого) завдяки різному. Тепер він підходить для розробки розширення коду frontend / SPA. Він також може розгортати додатки Docker і NodeJS. Це насправді не безкоштовно, але вони мають вільний план.


5
Я проста людина. Я бачу рішення, яке вимагає встановити npmна машину, яка, як відомо, є python, я підкреслив.
Парфянський розстріл

6
@ParthianShot: ви можете навчитися використовувати найкращий інструмент для роботи.
Дан Даскалеску

2
@ParthianShot У багатьох розробників вже встановлений вузол / npm. І назва питання є загальною для залучення великої аудиторії користувачів, які явно не переймаються питаннями python або SimpleHTTPServer, що підтверджується оновленнями. Це не тому, що вам не корисно, а це для всіх. Є вагомі причини не любити і Node, і Python. Такі речі, як leftpad / погана публікація / неправильне використання git, здаються мені абсолютно не пов'язаними.
Себастьян Лорбер

5
Додавання додаткової мови та основи несе технічну заборгованість та збільшує поверхню атаки навколишнього середовища. "Фатальні помилки можуть бути допущені в будь-якій мові програмування" Правда, але JS робить це легше, ніж більшість інших мов. І у кожної мови є ще; Чим менше мов ви використовуєте, тим менше ймовірність того, що якийсь розробник, який не знайомий з однією з мов, робить помилку, яка не була б помилкою в іншій мові.
Парфянський розстріл

2
Це як усиновлення дитини кожного разу, коли вам потрібна допомога по дому; це створює більше проблем, ніж вирішує в дорозі.
Парфянський розстріл

1

У мене була така ж проблема і я прийшов до цього рішення:

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

Я просто створив новий клас успадкування від SimpleHTTPRequestHandler, який лише змінює send_responseметод.


0

Вам потрібно буде надати власні екземпляри do_GET () (і do_HEAD (), якщо ви вирішите підтримати операції HEAD). щось на зразок цього:

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

Дякую за вашу відповідь, але я не маю жодного знання Python, що раніше, я просто використовую згаданий вище сценарій оболонки як простий сервер http для моїх програм Emberjs. Лише зіткнувшись із проблемою контролю доступу, я дослідив, щоб виявити, що мені потрібно ввімкнути це на цьому простому http-сервері. Тож після деяких досліджень я додав (увімкніть 'CrossOrigin', origingins => '*';), але не дивно, що це не спрацювало. Якщо ви можете, будь ласка, вкажіть мені на будь-який скрипт оболонки простого http-сервера Python, який включає в себе функцію контролю доступу, яка буде високо оцінена
MChan

З другого боку, я не намагаюся тут справді лінуватися, але почати вивчати пітон просто для того, щоб додати цю функцію до SimpleHTTP-сервера, на даний момент не звучить логічно, тому я сподівався, що це буде легко додати АБО сподіваюсь, що я можу знайти альтернативний / готовий сценарій Python, який може виконати цю роботу, щоб я міг продовжувати роботу над
розробкою

3
У SimpleHTTPServer немає опцій для підтримки контролю доступу. Або вам потрібно буде прокатати власний код - або перейти на інший веб-сервер, який підтримує контроль доступу. Подумайте про lighttpd.net
користувач590028
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.