问题:在简单的HTTP服务器上启用访问控制
对于非常简单的HTTP服务器,我具有以下shell脚本:
#!/bin/sh
echo "Serving at http://localhost:3000"
python -m SimpleHTTPServer 3000
我想知道我怎么可以启用或添加CORS标题喜欢Access-Control-Allow-Origin: *
到这台服务器?
回答 0
不幸的是,简单的HTTP服务器是如此简单,以至于它不允许任何自定义,尤其是不允许其发送的标头。但是,您可以使用的大部分内容自己创建一个简单的HTTP服务器SimpleHTTPRequestHandler
,而只需添加所需的标头即可。
为此,只需创建一个文件simple-cors-http-server.py
(或其他文件),然后根据所使用的Python版本,将以下代码之一放入其中。
然后,您可以执行操作python simple-cors-http-server.py
,它将启动修改后的服务器,该服务器将为每个响应设置CORS标头。
将shebang置于顶部,使该文件可执行并放入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)
回答 1
尝试其他替代方法,例如http-server
由于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
,它将创建一个https://$random.ngrok.com
允许任何人访问您的http://localhost:3000
服务器的URL 。它可以向世界展示您计算机本地运行的内容(包括本地后端/ API)localtunnel:与ngrok几乎相同
现在:运行时
now
,它将在线上传您的静态资产并将其部署到https://$random.now.sh
。除非您另有决定,否则它们将永远保持在线状态。由于差异,部署速度很快(第一个部署除外)。现在适用于生产前端/ SPA代码部署。它还可以部署Docker和NodeJS应用程序。它不是真正的免费,但他们有免费计划。
回答 2
我遇到了同样的问题,并提出了以下解决方案:
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
方法。
回答 3
您需要提供自己的do_GET()实例(如果选择支持HEAD操作,则需要提供do_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()