• Django restframework是怎么确定响应内容的格式的?关于HTTP协议的又一点认识。


    再用restframework编写接口的时候,会使用 APIView 和 rest_framework.response.Response,然后今天发现一个问题:

    我在用浏览器发送请求的时候,响应的是text/html, 返回的是一个页面

    以前调试的时候只知道这个页面真方便,真好看,另外我们的前端也没有反映过设么问题。

    直到今天测试Java的http请求,发现我获取的不是json!!!而是一个HTML文本,这真的是个大问题,试问如果有一天我用Java访问Django编写的服务端,正好服务端用了Response类,那么我拿到的是json???

    但是我用postman发起请求得到的就是json,诡异!

    当时就认为可能是请求头的问题,但是没往Accept上注意。

    真正的原因就是请求头里面的Accept字段,浏览器发起请求,该字段是:

    里面没有 application/json。

    优先解决办法: 在请求头添加 Accept:application/json

    问题到这里就解决了,后面是框架代码分析

    在Django restframework框架里,会有两个渲染类,

    这两个类是用来对所有Response相关类做渲染的,那么框架是怎么执行渲染的呢?

    APIView的dispatch方法,在得到响应后,会执行 finalize_response方法

    在红线处,会去执行一个操作,概括起来就是从请求头获取接受类型,以此来决定使用哪个渲染类:

    进入select_render方法:

    rest_framework.negotiation.DefaultContentNegotiation.select_renderer

     关键在两处标红处,第一处,分离出所有Accept类型,renderers就是上面的两个渲染类的列表,代码先后遍历两个渲染类,然后在第二个红标处进行匹配。

    如果请求头携带的Accept与任一个匹配,那么返回该渲染类。

    具体的,感兴趣的可以到这一块去看

    到这里,逻辑就走完了,最后回到这里:

    响应Response的渲染类被确定,框架最后使用该类执行渲染。

     框架调用该方法,输出渲染结果。

    这一坨代码真的让我一通好找!!!

    问题的主要原因是HTTP协议不熟悉,但是我之所以这么一通找,主要是想搞清楚,Restframework是怎么判定输出类型的

    所以,如果想让接口就输出json格式,一个办法是让调用者在请求头添加   Accept:*/* 或者 application/json;

    或者用下面的方式:

  • 相关阅读:
    递延收益为什么属于负债类科目
    java 环境变量脚本
    dotnet 执行命令常用代码
    centos安装nuget
    centos 安装nodejs redis
    linux git 记住密码
    libgit2-6311e88: cannot open shared object file: No such file or directory
    angular ng build 报错 Cannot read property 'default' of undefined
    java ObjectMapper json 与对象的相互转换
    java 流不能复用 stream has already been operated upon or closed 内存分页
  • 原文地址:https://www.cnblogs.com/haiton/p/14668577.html
Copyright © 2020-2023  润新知