Python 在简单的 HTTP 服务器上启用访问控制

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21956683/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 23:57:27  来源:igfitidea点击:

Enable access control on simple HTTP server

pythoncorssimplehttpserver

提问by MChan

I have the following shell script for a very simple HTTP server:

我有一个非常简单的 HTTP 服务器的以下 shell 脚本:

#!/bin/sh

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

I was wondering how I can enable or add a CORS headerlike Access-Control-Allow-Origin: *to this server?

我想知道我怎么可以启用或添加CORS标题喜欢Access-Control-Allow-Origin: *到这台服务器?

采纳答案by poke

Unfortunately, the simple HTTP server is really that simple that it does not allow any customization, especially not for the headers it sends. You can however create a simple HTTP server yourself, using most of SimpleHTTPRequestHandler, and just add that desired header.

不幸的是,简单的 HTTP 服务器真的很简单,它不允许任何自定义,尤其是它发送的标头。但是,您可以自己创建一个简单的 HTTP 服务器,使用大部分SimpleHTTPRequestHandler,然后添加所需的标头。

For that, simply create a file simple-cors-http-server.py(or whatever) and, depending on the Python version you are using, put one of the following codes inside.

为此,只需创建一个文件simple-cors-http-server.py(或其他文件),然后根据您使用的 Python 版本,将以下代码之一放入其中。

Then you can do python simple-cors-http-server.pyand it will launch your modified server which will set the CORS header for every response.

然后你可以这样做python simple-cors-http-server.py,它会启动你修改过的服务器,这将为每个响应设置 CORS 标头。

With the shebangat the top, make the file executable and put it into your PATH, and you can just run it using simple-cors-http-server.pytoo.

使用顶部的shebang,使文件可执行并将其放入您的PATH,您也可以使用它来运行它simple-cors-http-server.py

Python 3 solution

Python 3 解决方案

Python 3 uses SimpleHTTPRequestHandlerand HTTPServerfrom the http.servermoduleto run the server:

Python 3 使用SimpleHTTPRequestHandlerHTTPServer来自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 solution

Python 2 解决方案

Python 2 uses SimpleHTTPServer.SimpleHTTPRequestHandlerand the BaseHTTPServermoduleto run the server.

Python 2 使用SimpleHTTPServer.SimpleHTTPRequestHandlerBaseHTTPServer模块来运行服务器。

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

Python 2 & 3 解决方案

If you need compatibility for both Python 3 and Python 2, you could use this polyglot script that works in both versions. It first tries to import from the Python 3 locations, and otherwise falls back to Python 2:

如果您需要 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)

回答by user590028

You'll need to provide your own instances of do_GET() (and do_HEAD() if choose to support HEAD operations). something like this:

您需要提供自己的 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()

回答by Sebastien Lorber

Try an alternative like http-server

尝试像 http-server 这样的替代方案

As SimpleHTTPServer is not really the kind of server you deploy to production, I'm assuming here that you don't care that much about which tool you use as long as it does the job of exposing your files at http://localhost:3000with CORS headers in a simple command line

由于 SimpleHTTPServer 并不是您部署到生产中的那种服务器,我在这里假设您不太关心您使用的工具,只要它完成了http://localhost:3000使用 CORS 标头以简单的方式公开文件的工作命令行

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

#run
http-server -p 3000 --cors


Need HTTPS?

需要HTTPS吗?

If you need https in local you can also try caddyor certbot

如果您在本地需要 https,您也可以尝试caddycertbot



Some related tools you might find useful

一些您可能会觉得有用的相关工具

  • ngrok: when running ngrok http 3000, it creates an url https://$random.ngrok.comthat permits anyone to access your http://localhost:3000server. It can expose to the world what runs locally on your computer (including local backends/apis)

  • localtunnel: almost the same as ngrok

  • now: when running now, it uploads your static assets online and deploy them to https://$random.now.sh. They remain online forever unless you decide otherwise. Deployment is fast (except the first one) thanks to diffing. Now is suitable for production frontend/SPA code deployment It can also deploy Docker and NodeJS apps. It is not really free, but they have a free plan.

  • ngrok:运行时ngrok http 3000,它会创建一个https://$random.ngrok.com允许任何人访问您的http://localhost:3000服务器的 URL 。它可以向全世界公开在您的计算机上本地运行的内容(包括本地后端/api)

  • localtunnel: 几乎和 ngrok 一样

  • now:运行时now,它会在线上传您的静态资产并将它们部署到https://$random.now.sh. 除非您另有决定,否则它们将永远在线。由于 diffing,部署速度很快(第一个除外)。现在适用于生产前端/SPA 代码部署它还可以部署 Docker 和 NodeJS 应用程序。它不是真的免费,但他们有一个免费的计划。

回答by Hugo Trentesaux

I had the same problem and came to this solution:

我遇到了同样的问题并找到了这个解决方案:

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

I simply created a new class inheriting from SimpleHTTPRequestHandler that only changes the send_responsemethod.

我只是创建了一个继承自 SimpleHTTPRequestHandler 的新类,它只更改了send_response方法。