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. ...
随机推荐
- 多图详解Go的互斥锁Mutex
转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com 本文使用的go的源码时14.4 Mutex介绍 Mutex 结构体包含两个字段: 字段s ...
- Java源码赏析(六)Class<T> 类
目的 Class 类是每一个程序员都必须了解的,也是使用反射机制的基础. 这篇文章将Class 类的公共方法大致介绍了一遍(省略了安全.枚举.断言.注解相关代码). 代码 package java.l ...
- [从源码学设计]蚂蚁金服SOFARegistry 之 如何与Meta Server交互
[从源码学设计]蚂蚁金服SOFARegistry 之 如何与Meta Server交互 目录 [从源码学设计]蚂蚁金服SOFARegistry 之 如何与Meta Server交互 0x00 摘要 0 ...
- java基础:数组详解以及应用,评委打分案例实现,数组和随机数综合,附练习案列
1.数组 1.1 数组介绍 数组就是存储数据长度固定的容器,存储多个数据的数据类型要一致. 1.2 数组的定义格式 1.2.1 第一种格式 数据类型[] 数组名 示例: int[] arr; ...
- 2020年Spring Cloud最后一个大版本发布!
2020年12月22日,Spring Cloud 2020.0 正式发布GA版本! 版本说明 每次Spring Cloud的大版本发布,我们都要先弄清楚,它对应的Spring Boot版本是哪个! 该 ...
- Windows系统提示:“windows找不到文件请确定文件名是否正确后
最近使用Win7/10系统的用户反应在系统中移动了桌面上的一些与系统无关的文档,在挪动了文件之后出现的问题,弹出了windows找不到文件请确定文件名是否正确后,再试一次, 的错误提示,该怎么办呢? ...
- b站视频下载技术分享
最近无聊分析了一下b站的视频流协议,简单分享下爬取的流程. 首先先要找到视频对应的aid和cid,aid就相当于av号,而av号对应网页下的每一个视频都有对应的cid,普通视频就是分p,番剧就是集数, ...
- 面试官:数据库自增ID用完了会怎么样?
看到这个问题,我想起当初玩魔兽世界的时候,25H难度的脑残吼的血量已经超过了21亿,所以那时候副本的BOSS都设计成了转阶段.回血的模式,因为魔兽的血量是int型,不能超过2^32大小. 估计暴雪的设 ...
- 一个坑,bootstrap selectpicker 重置下拉列表时遇到的问题
需求是这样的:点击右侧三个按钮中的任意一个,如果执行成功,左侧的版本信息就需要重新获取列表.挺简单的需求,但是遇到了一个坑, 在使用$('#id').html('')清空下拉选项并且重新赋值的时候,始 ...
- node获取请求参数的方法get与post请求
1.get请求 get的请求参数是携带在url中的,因此需要引入url模块对请求进行解析,再使用url.parse()方法,get请求多用于页面跳转.表单等请求中,例如page页码.表单账号密码等 先 ...