HTTPS请求HTTP接口被浏览器阻塞,python实现websocket客户端,websocket服务器,跨域问题,dwebsocket,https,拦截,服务端
HTTPS请求HTTP接口被浏览器阻塞,python实现websocket客户端,websocket服务器,跨域问题,dwebsocket,https,拦截,服务端
发表时间:2020-03-05
1 背景
由于公司前端的页面部署在以https(加了证书)协议的域名下,去请求http协议的域名的某个服务,并且该http域名下的服务,不仅要处理普通请求(POST、GET),还需要处理websocket请求。由于浏览器禁止https域名的内容请求http的服务,甚至嵌入子页面都禁止,因为浏览器会认为http的内容是不安全的,所以为解决该问题,研究出如下解决方案。
2 解决办法
由于浏览器禁止,但是服务器并不会禁止,所以,我在https的域名下,解析一台代理服务器,由该代理服务器去代替https去请求,再把结果返给前端。
3 开发环境
PyCharm,语言:Python3,服务框架:django
4 用到的库
pip3 install Django==1.11.3 django-cors-headers==3.2.1 dwebsocket==0.5.12 websocket==0.2.1 websocket-client==0.57.0
5 settings.py配置
# 允许访问的host为所有
ALLOWED_HOSTS = ['*']
# 配置跨域请求问题
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_METHODS = (
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
'VIEW',
)
CORS_ALLOW_HEADERS = (
'XMLHttpRequest',
'X_FILENAME',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
)
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
#'myapp.apps.MyappConfig',
# 添加当前的app
'myapp',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 去除csrf校验
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
6 urls.py配置:
from django.contrib import admin
from django.urls import path
from django.conf.urls import url
from myapp import views
urlpatterns = [
path('admin/', admin.site.urls),
# 配置拦截/proxy 映射到 views.py中的方法
url(r'^proxy$',views.proxy),
]
7 views.py代码:仔细看注释
from django.shortcuts import render
from django.shortcuts import HttpResponse
import requests
from dwebsocket.decorators import accept_websocket
import logging
from websocket import create_connection
import time
# 设置日志格式
LOG_FORMAT = "%(asctime)s - %(levelname)s - %(message)s"
DATE_FORMAT = "%m/%d/%Y %H:%M:%S %p"
fs = logging.StreamHandler()
logging.basicConfig(level=logging.INFO, format=LOG_FORMAT, datefmt=DATE_FORMAT, handlers=[fs])
# Create your views here.
# 添加dwebsocket的装饰器,该装饰器会对request属性添加websocket属性
# 并添加 send()推数据 close()关闭连接 is_websocket()是否是websocket请求 等方法
@accept_websocket
def proxy(request):
# 判断请求是否是websocket
if not request.is_websocket():
# 收到的请求的格式是 https://devlab.edu.huaweicloud.com/proxy?url=http://ip:8000/senddata?model=workload-read-mostly
# 我们将这个服务部署到加了证书的服务器上,即可。
# 其中,参数url=后面是要代理的url ,我们将其截取下来,并重新请求。
url = request.get_full_path().split('url=')[1]
logging.info('proxy url : {}'.format(url))
# 进行GET请求和POST请求的分别处理
# if request.method == 'GET':
# logging.info('processing a url GET request !')
# 其中省略了将请求的 header/cookie 传递给代理请求的 header/cookie ,由于我们业务不需要这些,我就不加了。
# res = requests.get(url)
# else:
# logging.info('processing a url POST request !')
# res = requests.post(url)
# 由于我们的业务都是g GET 请求,所以就直接处理就好了
res = requests.get(url)
# 将代理请求的结果返回给真正的请求
logging.info('revc : {}'.format(res.content.decode()))
return HttpResponse(res.content.decode())
else:
# 收到的请求的格式是 wss://devlab.edu.huaweicloud.com/proxy?url=ws://ip:8000/senddata?model=workload-read-mostly
# 其中,参数url=后面是要代理的url ,我们将其截取下来,并重新请求。
url = request.get_full_path().split('url=')[1]
logging.info('proxy url : {}'.format(url))
try:
# 这里的header 必须要加上, 或者将 request中的header拿出来逐一存入list中,
# 由于request中保存的headers的格式是dict,websocket中需要的headers是list,所以需要自行转化,
# websocket的header的格式如下, 由于业务没有强制header 是什么,所以我就自己写的,但是注意,
# 需要将以下的header的内容都要补充完整,否则会报 header...相关的错误,返回200或者其他状态码的错误,
# 200在websocket是错误,在http里面是成功,需要注意一下。
header = ['Accept-Encoding: gzip, deflate',
'Connection: Upgrade',
'Pragma: no-cache',
'Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits',
'Sec - WebSocket - Version: 13',
'Upgrade: websocket',
'Access-Control-Allow-Origin: *',
'Access-Control-Allow-Headers: X-Requested-With',
'Access-Control-Allow-Methods: GET,POST,OPTIONS',
'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36']
# 创建长连接/websocket
ws = create_connection(url,header=header)
# 每1秒就收一下消息
while True:
# 接收消息,如果消息中带有Finished,表示消息都接收完毕,跳出循环。
res = ws.recv()
if 'Finished' in res:
logging.info('revc : {}'.format(res))
# 该服务,即作为服务端(接收并处理请求并响应方),又做为客户端(发送请求并接收另一个服务的响应)
# 所以将代理服务推过来的结果再推给浏览器
request.websocket.send(res)
# 调试的时候,浏览器端好像收不到最后一条消息,所以我在以这种方式再发送一遍吧
# return HttpResponse(res)
# websocket 相当占用网络资源,请及时关闭,由于生产环境中,网络资源的不稳定性,
# 可能数据还没推出去,就把websocket关闭了,会造成数据的丢失。
time.sleep(5)
ws.close()
request.websocket.close()
break
if not res == None:
logging.info('revc : {}'.format(res))
# 如果有数据, 将代理服务推过来的结果再推给浏览器
request.websocket.send(res)
time.sleep(1)
# websocket 相当占用网络资源,请及时关闭,其实逻辑是走不到这里的,但是还是加上保险
ws.close()
request.websocket.close()
except BaseException as e:
logging.error(e)
8 部署
python3 manage.py runserver 0.0.0.0:8080
https://www.pythonf.cn/read/51639
HTTPS请求HTTP接口被浏览器阻塞,python实现websocket客户端,websocket服务器,跨域问题,dwebsocket,https,拦截,服务端的更多相关文章
- 解决前后端分离的“两次请求”引出的Web服务器跨域请求访问问题的解决方案
在前后端分离的项目中,前端和后端可能是在不同的服务器上,也可以是Docker上,那就意味着前端请求后端Restful接口时,存在跨域情况. 后端在做了通用的跨域资源共享CORS设置后,前端在做ajax ...
- Chrome浏览器扩展开发系列之十五:跨域访问的XMLHttpRequest对象
XMLHttpRequest对象是W3C的标准API,用于访问服务器资源.XMLHttpRequest对象支持多种文本格式,如XML和JSON等.XMLHttpRequest对象可以通过HTTP和HT ...
- chrome浏览器下用jQuery的load函数来跨域加载页面,响应状态status为(canceled)是什么情况? JSON和JSONP,也许你会豁然开朗,含jQuery用例
http://www.cnblogs.com/dowinning/archive/2012/04/19/json-jsonp-jquery.html 问题来源:http://q.cnblogs.com ...
- 由一个“两次请求”引出的Web服务器跨域请求访问问题的解决方案
http://blog.csdn.net/cnhnnyzhy/article/details/53128179 (4)Access-Control-Max-Age 该字段可选,用来指定本次预检请求的有 ...
- Django之jsonp跨域请求原理
在进行网站开发的过程中经常会用到第三方的数据,但是由于同源策略的限制导致ajax不能发送请求,因此也无法获得数据.解决ajax的跨域问题有两种方法: 一.jsonp 二.XMLHttpRequest2 ...
- 深入理解jsonp跨域请求原理
在进行网站开发的过程中经常会用到第三方的数据,但是由于同源策略的限制导致ajax不能发送请求,因此也无法获得数据.解决ajax的跨域问题有两种方法: 一.jsop 二.XMLHttpRequest2中 ...
- springboot + websocket + spring-messaging实现服务器向浏览器广播式
目录结构 pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http:// ...
- Web 跨域请求问题的解决方案- CORS 方案
1.什么是跨域 跨域是指跨域名的访问,以下情况都属于跨域: 跨域现象 实例 域名不相同 www.baidu.com与www.taobao 一级域名相同,但是端口不相同 www.baidu.com:80 ...
- [二十七]SpringBoot 之 Restful接口的跨域请求
什么是跨域 简单的说即为浏览器限制访问A站点下的js代码对B站点下的url进行ajax请求.比如说,前端域名是www.abc.com,那么在当前环境中运行的js代码,出于安全考虑,访问www.xyz. ...
随机推荐
- BUUCTF 刮开有奖 WriteUp
题目链接 https://buuoj.cn/challenges#%E5%88%AE%E5%BC%80%E6%9C%89%E5%A5%96 题解 用IDA打开,按F5反编译,双击进入DialogFun ...
- .NET生态系统掠影
如果你是一名开发人员,想要进入到.NET的世界,你需要知道都有哪些可能.由于.NET Framework是..NET生态系统中最流行的技术,你可以用它来构建各种各样的应用程序,但是最近,出现了一些新的 ...
- VS批量添加多个文件
步骤 1.设置项目,显示所有文件.2.点击项目,右键在资源管理器中打开.3.将要导入的文件复制到对应的文件中去.4.在解决方案中就可以看到刚才添加的多个文件.5.在新加的文件夹上右键,包括在项目中.
- EXCEL2010分成多个窗口的,解决单个窗口显示多个文档的弊病
本操作需要修改注册表,请在修改之前导出要修改的项目以备份. 1.定位到[HKEY_CLASSES_ROOT\Excel.Sheet.12\shell\Open],导出保存.展开Open,将ddeexe ...
- 解决面具magisk刷入模块卡开机问题
手机刷入面具模块出现卡开机第二屏,在reccovery模式下,点击高级(advanced)->文件管理(File Manager)->data->adb->modules删掉对 ...
- 【超级经典】程序员装B指南(转)
一.准备工作 "工欲善其事必先利其器." 1.电脑不一定要配置高,但是双屏是必须的,越大越好,能一个横屏一个竖屏更好.一个用来查资料,一个用来写代码.总之要显得信息量很大,效率 ...
- 四元数和旋转(Quaternion & rotation)
四元数和旋转(Quaternion & rotation) 本篇文章主要讲述3D空间中的旋转和四元数之间的关系.其中会涉及到矩阵.向量运算,旋转矩阵,四元数,旋转的四元数表示,四元数表示的旋转 ...
- 配置NFS实现nginx动静分离
案例子任务一.安装配置NFS服务器 步骤1:使用docker容器配置NFS服务器 启动centos容器并进入 docker run -d --privileged centos:v1 /usr/sbi ...
- Centos7无网络下安装mysql5.7——mysql-rpm安装
本教程指将mysql安装到系统默认目录下,如想自定义修改目录,请在rpm安装时自行修改: rpm -ivh --prefix= /opt xxx.rpm #将xxx.rpm安装到/opt下 一.下载m ...
- Spark算子使用
一.spark的算子分类 转换算子和行动算子 转换算子:在使用的时候,spark是不会真正执行,直到需要行动算子之后才会执行.在spark中每一个算子在计算之后就会产生一个新的RDD. 二.在编写sp ...