Bật kiểm soát truy cập trên máy chủ HTTP đơn giản


121

Tôi có tập lệnh shell sau cho một máy chủ HTTP rất đơn giản:

#!/bin/sh

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

Tôi đã tự hỏi làm cách nào để có thể bật hoặc thêm tiêu đề CORS giống như Access-Control-Allow-Origin: *máy chủ này?

Câu trả lời:


197

Thật không may, máy chủ HTTP đơn giản thực sự đơn giản đến mức nó không cho phép bất kỳ tùy chỉnh nào, đặc biệt là không cho các tiêu đề mà nó gửi. Tuy nhiên, bạn có thể tự tạo một máy chủ HTTP đơn giản, sử dụng hầu hết SimpleHTTPRequestHandlervà chỉ cần thêm tiêu đề mong muốn đó.

Đối với điều đó, chỉ cần tạo một tệp simple-cors-http-server.py(hoặc bất cứ thứ gì) và tùy thuộc vào phiên bản Python bạn đang sử dụng, hãy đặt một trong các mã sau vào bên trong.

Sau đó, bạn có thể làm python simple-cors-http-server.pyvà nó sẽ khởi chạy máy chủ đã sửa đổi của bạn, máy chủ này sẽ đặt tiêu đề CORS cho mọi phản hồi.

Với shebang ở trên cùng, hãy làm cho tệp thực thi được và đưa nó vào PATH của bạn và bạn cũng có thể chạy nó bằng cách sử dụng simple-cors-http-server.py.

Giải pháp Python 3

Python 3 sử dụng SimpleHTTPRequestHandlerHTTPServertừ http.servermô-đun để chạy máy chủ:

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

Giải pháp Python 2

Python 2 sử dụng SimpleHTTPServer.SimpleHTTPRequestHandlerBaseHTTPServermô-đun để chạy máy chủ.

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

Giải pháp Python 2 & 3

Nếu bạn cần khả năng tương thích cho cả Python 3 và Python 2, bạn có thể sử dụng tập lệnh đa ngôn ngữ này hoạt động trong cả hai phiên bản. Đầu tiên, nó cố gắng nhập từ các vị trí Python 3, và nếu không sẽ quay trở lại 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)

Tôi đã làm theo hướng dẫn nhưng bằng cách thực thi python simple-cors-http-server.py tôi gặp lỗi: python: không thể mở tệp 'simple-cors-http-server.py': [Errno 2] Không có tệp hoặc thư mục nào bị đăng xuất .... bất kỳ suy nghĩ?
MChan

4
@poke Máy chủ phản hồi bằng phương thức 501 Không được hỗ trợ ('TÙY CHỌN'). Tôi đang chạy OS X 10.10.1 với Python 2.7.6. Bất kỳ đề xuất? 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 không hỗ trợ phương thức HTTP OPTIONS. Bạn có thể thêm nó nếu muốn (đọc hướng dẫn sử dụng Python về máy chủ HTTP); hoặc bạn không thể cố gắng truy cập vào máy chủ như vậy.
poke

2
@RobertoFenceschini Bạn có thể gặp phải các yêu cầu được đánh dấu trước yêu cầu OPTIONSphương thức được triển khai đúng cách. Đối với các yêu cầu đơn giản, giải pháp chỉ gửi Access-Control-Allow-Origintiêu đề vẫn hoạt động tốt.
poke

1
@ Tyguy7 Tuy nhiên, đó có thể là một hành vi chung với máy chủ HTTP đơn giản. Tôi đã có những kết quả khác nhau về hiệu suất trước đây. Nhưng để chạy một máy chủ trong chốc lát, tôi vẫn coi đó là giải pháp nhanh nhất.
poke

108

Hãy thử một thay thế như http-server

Vì SimpleHTTPServer không thực sự là loại máy chủ mà bạn triển khai để sản xuất, tôi giả sử ở đây rằng bạn không quan tâm nhiều đến việc bạn sử dụng công cụ nào miễn là nó thực hiện công việc hiển thị tệp của bạn http://localhost:3000với tiêu đề CORS một cách đơn giản. dòng lệnh

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

#run
http-server -p 3000 --cors

Cần HTTPS?

Nếu bạn cần https trong địa phương, bạn cũng có thể thử caddy hoặc certbot


Một số công cụ liên quan bạn có thể thấy hữu ích

  • ngrok : khi chạy ngrok http 3000, nó tạo ra một url https://$random.ngrok.comcho phép bất kỳ ai truy cập vào http://localhost:3000máy chủ của bạn . Nó có thể hiển thị với thế giới những gì chạy cục bộ trên máy tính của bạn (bao gồm cả phụ trợ / apis cục bộ)

  • localtunnel : gần giống như ngrok

  • bây giờ : khi chạy now, nó tải các tài sản tĩnh của bạn lên trực tuyến và triển khai chúng https://$random.now.sh. Họ vẫn trực tuyến mãi mãi trừ khi bạn quyết định khác. Triển khai nhanh chóng (ngoại trừ lần đầu tiên) nhờ sự khác biệt. Bây giờ phù hợp cho việc triển khai giao diện người dùng / mã SPA sản xuất Nó cũng có thể triển khai các ứng dụng Docker và NodeJS. Nó không thực sự miễn phí, nhưng họ có một kế hoạch miễn phí.


5
Tôi là một người đàn ông đơn giản. Tôi thấy một giải pháp yêu cầu cài đặt npmtrên một máy mà chỉ được biết là có python, tôi phản đối.
Parthian Shot vào

6
@ParthianShot: bạn có thể muốn học cách sử dụng công cụ tốt nhất cho công việc.
Dan Dascalescu

2
@ParthianShot Nhiều nhà phát triển đã cài đặt node / npm. Và tiêu đề câu hỏi đủ chung chung để thu hút một lượng lớn người dùng rõ ràng không quan tâm đến python hoặc SimpleHTTPServer, điều này đã được xác nhận bởi những người ủng hộ. Không phải vì nó không hữu ích cho bạn mà nó dành cho tất cả mọi người. Có nhiều lý do chính đáng để không thích cả Node và Python. Những thứ như leftpad / bad Publishing / bad git sử dụng dường như hoàn toàn không liên quan đến tôi.
Sebastien Lorber

5
Việc thêm một ngôn ngữ và khuôn khổ bổ sung sẽ dẫn đến nợ kỹ thuật tăng khả năng tấn công của môi trường. "Những sai lầm nghiêm trọng có thể mắc phải trong bất kỳ ngôn ngữ lập trình nào" Đúng, nhưng JS làm theo cách đó dễ dàng hơn hầu hết các ngôn ngữ khác. Và mọi ngôn ngữ đều có gotchas; bạn càng sử dụng ít ngôn ngữ thì càng ít có khả năng một nhà phát triển không quen với một trong các ngôn ngữ mắc lỗi mà không phải là một ngôn ngữ khác.
Parthian Shot

2
Điều này cũng giống như nhận nuôi một đứa trẻ mỗi khi bạn cần giúp đỡ xung quanh nhà; nó tạo ra nhiều vấn đề hơn là nó giải quyết được.
Parthian Shot

1

Tôi đã gặp vấn đề tương tự và đã đi đến giải pháp này:

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

Tôi chỉ đơn giản là tạo một lớp mới kế thừa từ SimpleHTTPRequestHandler chỉ thay đổi send_responsephương thức.


0

Bạn sẽ cần cung cấp các phiên bản do_GET () (và do_HEAD () của riêng mình nếu chọn hỗ trợ hoạt động HEAD). một cái gì đó như thế này:

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

Cảm ơn câu trả lời của bạn, nhưng tôi không có kiến ​​thức về Python, tôi chỉ đang sử dụng tập lệnh shell được đề cập ở trên làm máy chủ http đơn giản cho các ứng dụng Emberjs của tôi. Chỉ khi gặp sự cố kiểm soát truy cập, tôi mới nghiên cứu để thấy rằng tôi cần phải kích hoạt nó trong máy chủ http đơn giản này. Vì vậy, sau một số nghiên cứu, tôi đã thêm (kích hoạt 'CrossOrigin', origin => '*';) nhưng không ngạc nhiên khi nó không hoạt động. Nếu bạn có thể, vui lòng chỉ cho tôi bất kỳ tập lệnh shell máy chủ http đơn giản nào của Python bao gồm tính năng kiểm soát truy cập sẽ được đánh giá cao
MChan 22/02

Một lưu ý nhỏ, tôi không cố gắng lười biếng ở đây thực sự nhưng bắt đầu học python chỉ để thêm tính năng này vào máy chủ simpleHTTP nghe có vẻ không hợp lý vào thời điểm này vì vậy tôi hy vọng nó sẽ dễ dàng thêm HOẶC hy vọng tôi có thể tìm thấy một tập lệnh Python thay thế / đã sẵn sàng có thể thực hiện công việc để tôi có thể tiếp tục công việc nhà phát triển của mình
MChan 22/02

3
SimpleHTTPServer không có tùy chọn hỗ trợ kiểm soát truy cập. Bạn sẽ cần cuộn mã của riêng mình - hoặc chuyển sang máy chủ web khác hỗ trợ các điều khiển truy cập. Hãy suy nghĩ về lighttpd.net
user590028
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.