zoukankan      html  css  js  c++  java
  • 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;

    或者用下面的方式:

  • 相关阅读:
    Binary Tree Maximum Path Sum
    ZigZag Conversion
    Longest Common Prefix
    Reverse Linked List II
    Populating Next Right Pointers in Each Node
    Populating Next Right Pointers in Each Node II
    Rotate List
    Path Sum II
    [Leetcode]-- Gray Code
    Subsets II
  • 原文地址:https://www.cnblogs.com/haiton/p/14668577.html
Copyright © 2011-2022 走看看