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 相关文章推荐
Hadoop中的Python框架的使用指南
Apr 22 Python
探究python中open函数的使用
Mar 01 Python
python实现的AES双向对称加密解密与用法分析
May 02 Python
Python微信企业号开发之回调模式接收微信端客户端发送消息及被动返回消息示例
Aug 21 Python
opencv python 傅里叶变换的使用
Jul 21 Python
python二进制文件的转译详解
Jul 03 Python
pytorch 模型可视化的例子
Aug 17 Python
pytorch 预训练层的使用方法
Aug 20 Python
Python缓存技术实现过程详解
Sep 25 Python
解决django FileFIELD的编码问题
Mar 30 Python
详解Django中异步任务之django-celery
Nov 05 Python
Python 机器学习工具包SKlearn的安装与使用
May 14 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
解析使用ThinkPHP应该掌握的调试手段
2013/06/20 PHP
php中隐形字符65279(utf-8的BOM头)问题
2014/08/16 PHP
支付宝接口开发集成支付环境小结
2015/03/17 PHP
PHP中overload与override的区别
2017/02/13 PHP
namespace.js Javascript的命名空间库
2011/10/11 Javascript
js防止表单重复提交的两种方法
2013/09/30 Javascript
JavaScript通过prototype给对象定义属性用法实例
2015/03/23 Javascript
jQuery时间轴插件使用详解
2015/07/16 Javascript
jQuery实现最简单的切换图效果【可兼容IE6、火狐、谷歌、opera等】
2016/09/04 Javascript
常用原生js自定义函数总结
2016/11/20 Javascript
AngularJS过滤器filter用法分析
2016/12/11 Javascript
JavaScript 动态三角函数实例详解
2017/01/08 Javascript
JS实现的tab切换选项卡效果示例
2017/02/28 Javascript
Node.js 中exports 和 module.exports 的区别
2017/03/14 Javascript
使用Bootstrap + Vue.js实现表格的动态展示、新增和删除功能
2017/11/27 Javascript
JavaScript 点击触发复制功能实例详解
2018/11/02 Javascript
详解Vue组件之间通信的七种方式
2019/04/14 Javascript
JS 自执行函数原理及用法
2019/08/05 Javascript
vue+element树组件 实现树懒加载的过程详解
2019/10/21 Javascript
javascript设计模式 ? 简单工厂模式原理与应用实例分析
2020/04/09 Javascript
vue如何搭建多页面多系统应用
2020/06/17 Javascript
JS可断点续传文件上传实现代码解析
2020/07/30 Javascript
jQuery实现鼠标拖拽登录框移动效果
2020/09/13 jQuery
javascript实现固定侧边栏
2021/02/09 Javascript
Python使用re模块正则提取字符串中括号内的内容示例
2018/06/01 Python
Python如何调用JS文件中的函数
2019/08/16 Python
详解pyinstaller selenium python3 chrome打包问题
2019/10/18 Python
python requests抓取one推送文字和图片代码实例
2019/11/04 Python
Python利用逻辑回归分类实现模板
2020/02/15 Python
俄罗斯极限运动网上商店:Board Shop №1
2020/12/18 全球购物
Java如何读取CLOB字段
2013/10/10 面试题
心得体会范文
2014/01/04 职场文书
初三家长会邀请函
2014/01/18 职场文书
优秀班组事迹材料
2014/12/24 职场文书
2015年社区民政工作总结
2015/04/21 职场文书
详解Go语言运用广度优先搜索走迷宫
2021/06/23 Python