python3 http.server跨域处理,亲测有效

在用python3创建简单http服务器时,碰到跨域问题,网上找的大多数方法都不行,下面整理出解决方法,亲测有效。

一、代码

import json
from http.server import HTTPServer
from http.server import SimpleHTTPRequestHandler
import socketserver
import socket

class MyRequestHandler(SimpleHTTPRequestHandler):

    def _send_cors_headers(self):
        """ Sets headers required for CORS """
        self.send_header('Content-type', 'application/json')
        self.send_header("Access-Control-Allow-Origin", "*")
        self.send_header("Access-Control-Allow-Methods", "*")
        self.send_header("Access-Control-Allow-Headers", "Authorization, Content-Type")

    def do_GET(self):
        print(self.path)
        if self.path == "/get_ipaddr":
            req = {'code': "0", 'msg': 'OK', 'ipaddr': socket.gethostbyname(socket.gethostname())}
        else:
            req = {'code': "4103", 'msg': 'path error'}

        self.send_response(200)
        self._send_cors_headers()
        self.end_headers()
        rspstr = json.dumps(req)
        self.wfile.write(rspstr.encode("utf-8"))

    def do_OPTIONS(self):
        self.send_response(200)
        self._send_cors_headers()
        self.end_headers()

    def do_POST(self):
    	if self.path == "/login":
            req = {'code': "0", 'msg': 'OK'}
        else:
            req = {'code': "4103", 'msg': 'path error'}

        self.send_response(200)
        self._send_cors_headers()
        self.end_headers()
        rspstr = json.dumps(req)
        self.wfile.write(rspstr.encode("utf-8"))

if __name__ == '__main__':
	server_host = '127.0.0.1'
    server_port = 8000
    httpd = socketserver.TCPServer((server_host, server_port), MyRequestHandler)
    print('exe_server started on ' + str(server_host) + ' server_port:' + str(server_port))
    httpd.serve_forever()

说明: 解决跨域的关键代码:self.send_header("Access-Control-Allow-Headers", "Authorization, Content-Type")

二、HTTP 响应首部字段说明

1. Access-Control-Allow-Origin

响应首部中可以携带一个 Access-Control-Allow-Origin 字段,其语法如下:

Access-Control-Allow-Origin: | *
其中,origin 参数的值指定了允许访问该资源的外域 URI。对于不需要携带身份凭证的请求,服务器可以指定该字段的值为通配符,表示允许来自所有域的请求。

例如,下面的字段值将允许来自 http://mozilla.com 的请求:

Access-Control-Allow-Origin: http://mozilla.com
如果服务端指定了具体的域名而非“*”,那么响应首部中的 Vary 字段的值必须包含 Origin。这将告诉客户端:服务器对不同的源站返回不同的内容。

2. Access-Control-Expose-Headers

译者注:在跨源访问时,XMLHttpRequest对象的getResponseHeader()方法只能拿到一些最基本的响应头,Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma,如果要访问其他头,则需要服务器设置本响应头。

Access-Control-Expose-Headers 头让服务器把允许浏览器访问的头放入白名单,例如:

Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header
这样浏览器就能够通过getResponseHeader访问X-My-Custom-Header和 X-Another-Custom-Header 响应头了。

3. Access-Control-Max-Age

Access-Control-Max-Age 头指定了preflight请求的结果能够被缓存多久,请参考本文在前面提到的preflight例子。

Access-Control-Max-Age:
delta-seconds 参数表示preflight请求的结果在多少秒内有效。

4. Access-Control-Allow-Credentials

Access-Control-Allow-Credentials 头指定了当浏览器的credentials设置为true时是否允许浏览器读取response的内容。当用在对preflight预检测请求的响应中时,它指定了实际的请求是否可以使用credentials。请注意:简单 GET 请求不会被预检;如果对此类请求的响应中不包含该字段,这个响应将被忽略掉,并且浏览器也不会将相应内容返回给网页。

Access-Control-Allow-Credentials: true
上文已经讨论了附带身份凭证的请求。

5. Access-Control-Allow-Methods

Access-Control-Allow-Methods 首部字段用于预检请求的响应。其指明了实际请求所允许使用的 HTTP 方法。

Access-Control-Allow-Methods: [, ]*
相关示例见这里。

6. Access-Control-Allow-Headers

Access-Control-Allow-Headers 首部字段用于预检请求的响应。其指明了实际请求中允许携带的首部字段。

Access-Control-Allow-Headers: [, ]*

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值