【Django后端】微信小程序post请求返回403或者500的解决方案

您所在的位置:网站首页 微信显示403 【Django后端】微信小程序post请求返回403或者500的解决方案

【Django后端】微信小程序post请求返回403或者500的解决方案

2024-07-15 16:27| 来源: 网络整理| 查看: 265

单纯使用Django为微信小程序提供后端接口,我负责后端接口、同学负责前端,我们测试了get请求是没有问题的,但是在发送post请求时,前端收到的返回值一直是500和403。 (PS:想直接看解决方法的可以点击下方的“解决方案”跳转过去)

目录 1.返回 500(服务器错误)1.1前端代码1.2后端接口1.3尝试的办法1.3.1修改前端 header1.3.2修改后端获取参数的方式 2.返回 403(禁止访问,服务器收到请求,但拒绝提供服务)2.1尝试的办法2.1.1修改nginx相关配置 3.解决方案4.总结

1.返回 500(服务器错误) 1.1前端代码

在这里插入图片描述

1.2后端接口 def get2(request): if requesthod == "POST": id = request.POST.get('id') return HttpResponse({"result": id+5})

从上面的前端代码可以看得到,url的最后是没有加 / 的,其得到的返回值是500,然后我在后端接口把if语句删除,直接返回,但是前端的返回值依然不变,还是500。

1.3尝试的办法 1.3.1修改前端 header

在网上搜到一些资料,说是将前端代码的header修改:

header = { 'content-type': 'application/x-www-form-urlencoded', }

修改完以后仍然是错误的,返回值依然是500。

1.3.2修改后端获取参数的方式

看了很多资料以后,我感觉前端代码的写法没有问题,于是我认为是后端获取post请求的参数时出现了错误,我就尝试使用别的方式获取参数:

第一种 def get2(request): req_data = self.request.body req_data = json.loads(req_data) id = req_data.get('id') return HttpResponse({"result": id+5}) 第二种 def get2(request): id = request.data['id'] return HttpResponse({"result": id+5})

上述两种办法都不行,返回值依然是500,此时我感觉很奇怪,我就想看看这些请求发过来以后经历了什么。于是我将后端代码加了一句print语句,判断请求的类型:

def get2(request): print(requesthod) id = request.POST.get('id') return HttpResponse({"result": id+5})

输出结果让我大吃一惊,因为它输出的是“GET”,那么请求的返回值是500就很容易理解了,因为我一直是使用获取POST请求参数的格式,所以服务就发生了错误返回500。然后我去查询请求的记录,我发现每一个POST请求的返回值都是301(也就是永久性重定向:本网页被永久性转移到另一个URL)。于是我去搜索原因,解决以后就出现了下面的问题。

2.返回 403(禁止访问,服务器收到请求,但拒绝提供服务)

通过前面的分析,我感觉事情很奇怪,因为每个POST请求都被永久性重定向了,查询了一些资料后我才了解到:django在url定向的时候,如果末尾不是‘/’,会被系统重定向到带‘/’的url,即301,然后空的请求被重定向,就变成了get。 如此我兴奋地让前端的同学把url最后面加上了 / ,但是一测试,返回值变成了403。

2.1尝试的办法 2.1.1修改nginx相关配置

因为部署django项目时是使用的nginx+uwsgi,在网上看到有人说nginx可能导致post请求返回403,搜了一些资料,感觉解决方法都比较麻烦,因此没有采用。(大家可以自行搜索一下)

3.解决方案

在搜索POST请求总是返回403时,偶然看到一个资料,其中提到这是一个跨域请求问题

(Django 中表单所需的 CSRF模板标签可防止跨站点请求伪造。CSRF使客户端浏览器访问过的恶意站点可以向您自己的服务器发出请求。因此,django 提供的 csrf_token 使您的 django服务器和站点可以轻松地免受此类恶意攻击。如果您的表单不受 csrf_token 保护,django 将返回 403禁止页面。这是对您网站的一种保护形式,尤其是在未故意遗漏令牌时。)

但是在某些情况下,django 站点不想使用 csrf_token 保护其表单,故Django提供了一个装饰器**@csrf_exempt**,此装饰器将视图标记为不受中间件确保的保护。 所以做出如下修改:

#在程序中导入csrf_exempt from django.views.decorators.csrf import csrf_exempt #在想接受POST请求的函数前面加上 @csrf_exempt @csrf_exempt def get2(request): print(requesthod) id = request.POST.get('id') return HttpResponse({"result": id+5})

如此前端的请求就可以正常得到返回值了,返回状态为200。

4.总结 前端的url需要以 / 结尾修改前端 ‘content-type’ header = { 'content-type': 'application/x-www-form-urlencoded', } 后端接口函数前面加 @csrf_exempt from django.views.decorators.csrf import csrf_exempt @csrf_exempt def get2(request): print(requesthod) id = request.POST.get('id') return HttpResponse({"result": id+5})

如果有不正确的地方请大家指正,感谢大家。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3