“跨域请求 Cross-Origin Resource Sharing(CORS) 被禁止”这个问题,应该很常见了,网上也有很多解释原因和解决方案的文章。
鉴于网上搜到的文章内容比较长,讲得也比较细,我这里就列举一些,几种平台(主要是我目前用到的)允许跨域请求的方法。
- 用nginx。我暂时没用到,跳过。以后用到了,再补充。
- 设置谷歌浏览器。
- 设置python的wsgiref搭建的web服务器的响应头。
- 设置django的响应头。
- 设置全局django。我暂时没用到,跳过。以后用到了,再补充。
以下为详细说明。
1. 用nginx。我暂时没用到,跳过。以后用到了,再补充。
2. 谷歌浏览器,通过设置快捷方式禁用部分设置。
创建chrome浏览器的快捷方式,在属性中找到打开路径,在…chrome.exe后面加上
--args --disable-web-security --user-data-dir="C:/ChromeDevSession",比如,我的谷歌浏览器chrome.exe的快捷方式的打开路径,可以修改为:C:\Users\qcy\AppData\Local\Google\Chrome\Application\chrome.exe --disable-web-security --user-data-dir="C:/ChromeDevSession"
3. 用python的wsgiref快速搭建的web服务器,在http响应头中增加允许访问的主机所在的域。
"""
提供web数据服务
"""
from wsgiref.simple_server import make_server
import datetime
from urllib.parse import parse_qs
import json
class DateEncoder(json.JSONEncoder):
"""
这里可以写上对各种不能通过 json.dumps 这个函数
直接序列化的处理方式。
"""
def default(self, obj):
if isinstance(obj, datetime.datetime):
return obj.strftime("%Y-%m-%d %H:%M:%S")
elif isinstance(obj, datetime.date):
return obj.strftime("%Y-%m-%d")
else:
return json.JSONEncoder.default(self, obj)
def get_response(environ, response):
# response 如下调用就会发送HTTP响应的Header,注意只能调用一次start_response()函数发送Header。
# response 函数两个参数,一是HTTP响应码,一是一组list表示的HTTP Header,每个Header用一个包含两个str的数组表示
# 这个编号是给协议的
status = '200 OK'
# response_headers 中添加请求头部 ,解决跨域问题
response_headers = [('Content-type', 'application/json'),
('Access-Control-Allow-Origin', '*'), # * 表示任意域名都可以跨域访问
('Access-Control-Allow-Methods', 'POST'),
('Access-Control-Allow-Headers', 'x-requested-with,content-type'),
] # json
response(status, response_headers)
# 获取web端需要的data
# 用environ['PATH_INFO']获取路径,做简单的路由
print(environ['PATH_INFO'])
path_info = environ['PATH_INFO']
if path_info == '/node_detail/':
# 这里可以查询由GET请求提交过来的参数
request_field_dict = parse_qs(environ['QUERY_STRING'])
start_yyyymmdd = request_field_dict.get('start_yyyymmdd')[0]
end_yyyymmdd = request_field_dict.get('end_yyyymmdd')[0]
graph_name = request_field_dict.get('graph_name')[0]
node_name = request_field_dict.get('node_name')[0]
data_dict = dict()
data_json_str = '这里是一个可以转换为dict的json字符串'
data_dict['driving_factor'] = json.loads(data_json_str)
# 这个编号是给前端处理的
response_dict = {
"code": 200,
"msg": "success",
"data": data_dict,
}
binary_data_json = json.dumps(response_dict, cls=DateEncoder).encode('utf-8')
return [binary_data_json]
if __name__ == '__main__':
http = make_server('', 8000, get_response)
print('server in 8000....')
http.serve_forever()
4. django框架下,在http响应头中增加允许跨域访问的主机所在的域。以下这段代码,改编自pyecharts项目的整合django项目的示例代码。这是在django框架的一个APP下面view文件。
import json
from random import randrange
from django.http import HttpResponse
from rest_framework.views import APIView
from pyecharts.charts import Bar
from pyecharts import options as opts
# Create your views here.
def response_as_json(data):
json_str = json.dumps(data)
response = HttpResponse(
json_str,
content_type="application/json",
)
response["Access-Control-Allow-Origin"] = "*"
return response
def json_response(data, code=200):
data = {
"code": code,
"msg": "success",
"data": data,
}
return response_as_json(data)
def json_error(error_string="error", code=500, **kwargs):
data = {
"code": code,
"msg": error_string,
"data": {}
}
data.update(kwargs)
return response_as_json(data)
JsonResponse = json_response
JsonError = json_error
def bar_base() -> Bar:
c = (
Bar()
.add_xaxis(["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"])
.add_yaxis("商家A", [randrange(0, 100) for _ in range(6)])
.add_yaxis("商家B", [randrange(0, 100) for _ in range(6)])
.set_global_opts(title_opts=opts.TitleOpts(title="Bar-基本示例", subtitle="我是副标题"))
.dump_options_with_quotes()
)
return c
class ChartView(APIView):
def get(self, request, *args, **kwargs):
return JsonResponse(json.loads(bar_base()))
5.?django项目的全局设置,暂时没有用到,以后补充。
(完)
|