Django

django rest_framework 自动生成的文档不走https引发跨域问题

简介:通过配置schema_url,让drf文档可以通过https访问,解决浏览器跨域问题

最近在用django搭建服务器时,集成了rest_framework(简称drf),并且使用了drf的api文档功能。一切都很顺利,只是在使用drf文档时,原本https的请求,在点击drf文档的某个提交按钮时,请求被浏览器拦截了,原因是https的站点访问了http的请求。
截屏2019-08-13下午11.19.27.png

如上图,通过chrome调试找到了问题的根源,原本站点是使用https的协议,但是drf文档的提交按钮隐藏的链接尽然是http的。

通过chrome继续调试,发现window.schema的被中的schema.js文件为url":"http://chat.enba.com/api/docs/schema.js",而在提交按钮的点击事件中,将schema作为参数传入,然后通过schema中url获取是http还是https协议,最终拼接成提交按钮的请求url。

Snip20190814_1.png
上图的参数document就是传递过来的schema,原本应该是https的请求,却搞成http请求,就是这个schema搞的鬼。

我在最初通过chrome调试时,发觉在rest_framework的schema.jswindow.schema来自window.atob('{{ schema }}'
Snip20190814_2.png
上图{{ schema }}为django的模版中引用了django的代码。我在rest_frameworkschemas.py中找到了定义schema的代码。
Snip20190814_4.png
Snip20190814_7.png
上图,可以看到在SchemaJSRendererrender方法定义了schema,并且被渲染到模版上:

class SchemaJSRenderer(BaseRenderer):
    media_type = 'application/javascript'
    format = 'javascript'
    charset = 'utf-8'
    template = 'rest_framework/schema.js'

    def render(self, data, accepted_media_type=None, renderer_context=None):
        codec = coreapi.codecs.CoreJSONCodec()
        schema = base64.b64encode(codec.encode(data))

        template = loader.get_template(self.template)
        context = {'schema': mark_safe(schema)}
        request = renderer_context['request']
        return template_render(template, context, request=request)

而在最初调试时,我们在chrome的debuger界面看到schema.js中的window.schema正是这个内容。
截屏2019-08-14上午12.48.51.png

最终,锁定问题发生在Django-restframework 的 schema_url配置上。

在修改这个问题钱,还需要对drf的SchemaView有一些了解,正好这篇文章有所介绍。

配置drf文档的url为以下:

url(r'api/docs/', include_docs_urls(title="websocket api docs", schema_url="http://chat.enba.com/")),

至此,问题解决。

推荐阅读

目录