python bottle框架支持jquery ajax的RESTful风格的PUT和DELETE方法


Posted in Python onMay 24, 2017

这两天在用python的bottle框架开发后台管理系统,接口约定使用RESTful风格请求,前端使用jquery ajax与接口进行交互,使用POST与GET请求时都正常,而Request Method使用PUT或DELETE请求时,直接爆“HTTP Error 405: Method Not Allowed”错误。而ajax提交的Request Method值DELETE也变成了OPTIONS了。

python bottle框架支持jquery ajax的RESTful风格的PUT和DELETE方法

度娘了好多答案,要么说是浏览器不支持,要么说自己重新封装jquery,还有其他的一些方法......呃...重新封装jquery就算了,javascript不是很熟无从下手,然后其他方法一个个都试过也没有用,想来想去还是从python源码入手好一点。

说干就干,在主文件main.py中,添加了bottle勾子 @hook('before_request') 函数(引用:from bottle import request),然后添加r = request,用来接收bottle的request变量,方便debug时在IDE的Debugger视图中查看request里面的值,见下图

python bottle框架支持jquery ajax的RESTful风格的PUT和DELETE方法

我们找到request的environ变量,可以看到用ajax提交时,比平常提交多了'HTTP_ACCESS_CONTROL_REQUEST_METHOD' (64411616) = {str}'DELETE' 参数

python bottle框架支持jquery ajax的RESTful风格的PUT和DELETE方法

而Request Method的值则变为:'REQUEST_METHOD' (45248088) = 'OPTIONS' ,难怪jquery的ajax方式提交,python bottle框架设定的路由一直接收不到

python bottle框架支持jquery ajax的RESTful风格的PUT和DELETE方法

知道问题所在要改造就好多了

方法一:直接在勾子里添加下面代码,改变REQUEST_METHOD的值

@hook('before_request')
def validate():
  """使用勾子处理页面或接口访问事件"""
  # 让bottle框架支持jquery ajax的RESTful风格的PUT和DELETE等请求
  REQUEST_METHOD = request.environ.get('REQUEST_METHOD')
  HTTP_ACCESS_CONTROL_REQUEST_METHOD = request.environ.get('HTTP_ACCESS_CONTROL_REQUEST_METHOD')
  if REQUEST_METHOD == 'OPTIONS' and HTTP_ACCESS_CONTROL_REQUEST_METHOD:
    request.environ['REQUEST_METHOD'] = HTTP_ACCESS_CONTROL_REQUEST_METHOD

方法二:修改bottle调用模块的源码

通过debug,我们可以发现,bottle.py调用wsgiref.simple_server模块中,class WSGIRequestHandler(BaseHTTPRequestHandler)类的def get_environ(self)方法是用来设置request的environ变量

python bottle框架支持jquery ajax的RESTful风格的PUT和DELETE方法

所以我们只需要在return env前添加处理代码就可以了,具体见下面代码

class WSGIRequestHandler(BaseHTTPRequestHandler):

  server_version = "WSGIServer/" + __version__

  def get_environ(self):
    env = self.server.base_environ.copy()
    env['SERVER_PROTOCOL'] = self.request_version
    env['SERVER_SOFTWARE'] = self.server_version
    env['REQUEST_METHOD'] = self.command
    if '?' in self.path:
      path,query = self.path.split('?',1)
    else:
      path,query = self.path,''

    env['PATH_INFO'] = urllib.parse.unquote(path, 'iso-8859-1')
    env['QUERY_STRING'] = query

    host = self.address_string()
    if host != self.client_address[0]:
      env['REMOTE_HOST'] = host
    env['REMOTE_ADDR'] = self.client_address[0]

    if self.headers.get('content-type') is None:
      env['CONTENT_TYPE'] = self.headers.get_content_type()
    else:
      env['CONTENT_TYPE'] = self.headers['content-type']

    length = self.headers.get('content-length')
    if length:
      env['CONTENT_LENGTH'] = length

    for k, v in self.headers.items():
      k=k.replace('-','_').upper(); v=v.strip()
      if k in env:
        continue          # skip content length, type,etc.
      if 'HTTP_'+k in env:
        env['HTTP_'+k] += ','+v   # comma-separate multiple headers
      else:
        env['HTTP_'+k] = v

    # 让bottle框架支持jquery ajax的RESTful风格的PUT和DELETE等请求
    if 'REQUEST_METHOD' in env and env['REQUEST_METHOD'] == 'OPTIONS' and 'HTTP_ACCESS_CONTROL_REQUEST_METHOD' in env:
      env['REQUEST_METHOD'] = env['HTTP_ACCESS_CONTROL_REQUEST_METHOD']

    return env

重新启动python服务后,我们再次提交一下ajax,就可以发现提交成功了,检查http请求头,Request Method的值还是OPTIONS,但服务器已经可以正常接收请求了

python bottle框架支持jquery ajax的RESTful风格的PUT和DELETE方法

以上这篇python bottle框架支持jquery ajax的RESTful风格的PUT和DELETE方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

原文地址:http://www.cnblogs.com/EmptyFS/p/6895479.html

Python 相关文章推荐
python实现的一只从百度开始不断搜索的小爬虫
Aug 13 Python
Linux系统上Nginx+Python的web.py与Django框架环境
Dec 25 Python
Python设计足球联赛赛程表程序的思路与简单实现示例
Jun 28 Python
Python实现拷贝多个文件到同一目录的方法
Sep 19 Python
python 爬虫一键爬取 淘宝天猫宝贝页面主图颜色图和详情图的教程
May 22 Python
pytorch + visdom CNN处理自建图片数据集的方法
Jun 04 Python
利用Pycharm断点调试Python程序的方法
Nov 29 Python
Python正则表达式匹配和提取IP地址
Jun 06 Python
python通过robert、sobel、Laplace算子实现图像边缘提取详解
Aug 21 Python
解决Python pip 自动更新升级失败的问题
Feb 21 Python
python实现密码验证合格程序的思路详解
Jun 01 Python
python中xlutils库用法浅析
Dec 29 Python
Python生成密码库功能示例
May 23 #Python
Python计算两个日期相差天数的方法示例
May 23 #Python
基于Python_脚本CGI、特点、应用、开发环境(详解)
May 23 #Python
浅谈django model的get和filter方法的区别(必看篇)
May 23 #Python
Python常用内置模块之xml模块(详解)
May 23 #Python
Python使用PyCrypto实现AES加密功能示例
May 22 #Python
django+js+ajax实现刷新页面的方法
May 22 #Python
You might like
Oracle 常见问题解答
2006/10/09 PHP
通过5个php实例细致说明传值与传引用的区别
2012/08/08 PHP
PHP图片自动裁切应付不同尺寸的显示
2014/10/16 PHP
在Windows XP下安装Apache+MySQL+PHP环境
2015/02/22 PHP
PHP获取不了React Native Fecth参数的解决办法
2016/08/26 PHP
php输出含有“#”字符串的方法
2017/01/18 PHP
laravel通过创建自定义artisan make命令来新建类文件详解
2017/08/17 PHP
如何实现浏览器上的右键菜单
2006/07/10 Javascript
找到一点可怜的关于dojo资料,谢谢作者!
2006/12/06 Javascript
javascript实例--教你实现扑克牌洗牌功能
2014/05/15 Javascript
jQuery插件StickUp实现网页导航置顶
2015/04/12 Javascript
jQuery 获取select选中值及清除选中状态
2016/12/13 Javascript
Angular 2.x学习教程之结构指令详解
2017/05/25 Javascript
php register_shutdown_function函数详解
2017/07/23 Javascript
webpack分离css单独打包的方法
2018/06/12 Javascript
vue-router中的hash和history两种模式的区别
2018/07/17 Javascript
layer提示框添加多个按钮选择的实例
2019/09/12 Javascript
nodejs开发一个最简单的web服务器实例讲解
2020/01/02 NodeJs
js中火星坐标、百度坐标、WGS84坐标转换实现方法示例
2020/03/02 Javascript
vue+vant实现购物车全选和反选功能
2020/11/17 Vue.js
Python新手实现2048小游戏
2015/03/31 Python
Python中文件I/O高效操作处理的技巧分享
2017/02/04 Python
python判断是空的实例分享
2020/07/06 Python
加拿大便宜的隐形眼镜商店:Clearly
2016/09/15 全球购物
法国票务网站:Ticketmaster法国
2018/07/09 全球购物
Etam德国:内衣精品店
2019/08/25 全球购物
澳大利亚领先的女性运动服品牌:Lorna Jane
2020/06/19 全球购物
班主任评语大全
2014/04/26 职场文书
2014年政风行风工作总结
2014/11/22 职场文书
营业员岗位职责
2015/02/11 职场文书
2015年高中班级工作总结
2015/07/21 职场文书
珍爱生命主题班会
2015/08/13 职场文书
php 防护xss,PHP的防御XSS注入的终极解决方案
2021/04/01 PHP
python实现高效的遗传算法
2021/04/07 Python
基于JavaScript实现年月日三级联动
2021/06/22 Javascript