美文网首页
难忘的301 Moved Permanently (from d

难忘的301 Moved Permanently (from d

作者: ikeaforever | 来源:发表于2020-01-06 22:13 被阅读0次

一、事件回顾:
早上django写好代码,和前端联调代码。

  1. 获取数据列表OK
  2. 获取数据详情301,但是仍然能获取到数据
  3. 修改接口后OK
  4. 数据修改后准备再次修改。首先,获取详情数据(301 Moved Permanently (from disk cache))渲染竟然还是之前的详情数据w(゚Д゚)w,直接从缓存获取数据,我的天哪,数据乱掉了
  5. 清除浏览器缓存,postman请求,没有问题啊,到底是怎么回事(⊙_⊙)?

二、思考和排查

  1. 为啥有301,首先看是否为服务端返回的301,一看日志,竟然看到了301,纳尼,还以为是前端的锅
  2. 继续排查,仔细观察url,幸亏眼神好,发现url最后没有斜杠(/),脑袋灵光一闪,难道是因为最后没有加斜杠,赶紧让前端加上
  3. 联调继续,发现问题完美解决

三、解剖问题
1、为啥哟?为啥加上就可以了?(⊙_⊙)? 后面的斜杠到底为啥哟?忽然想起来了django有个配置APPEND_SLASH,看来多读官方文档还是有好处的。
2、官方文档粗糙翻译:
配置名-是否追加斜杠(APPEND_SLASH):默认为True,当配置设置为True的时候,请求URL匹配不到任何URL配置中的pattern,而且其url后缀没有斜杠,一个重定向到请求url加斜杠(/)发生了。而且要注意,重定向可能会导致POST的请求数据丢失。
而且这个配置仅仅会在配置了 CommonMiddleware这个中间件才生效。所以一定是CommonMiddleware对请求做了处理
3、代码剖析

    def process_request(self, request):

        # 客户端检测,立马响应不被允许的用户客户端
        if 'HTTP_USER_AGENT' in request.META:
            for user_agent_regex in settings.DISALLOWED_USER_AGENTS:
                if user_agent_regex.search(request.META['HTTP_USER_AGENT']):
                    logger.warning('Forbidden (User agent): %s', request.path,
                        extra={
                            'status_code': 403,
                            'request': request
                        }
                    )
                    return http.HttpResponseForbidden('<h1>Forbidden</h1>')

        # 检查是否处理斜杠(/)后缀
        # and settings.PREPEND_WWW
        host = request.get_host()
        old_url = [host, request.path]
        new_url = old_url[:]

        if (settings.PREPEND_WWW and old_url[0] and
                not old_url[0].startswith('www.')):
            new_url[0] = 'www.' + old_url[0]

        # Append a slash if APPEND_SLASH is set and the URL doesn't have a
        # trailing slash and there is no pattern for the current path
        if settings.APPEND_SLASH and (not old_url[1].endswith('/')):
            urlconf = getattr(request, 'urlconf', None)
            if (not urlresolvers.is_valid_path(request.path_info, urlconf) and
                    urlresolvers.is_valid_path("%s/" % request.path_info, urlconf)):
                new_url[1] = new_url[1] + '/'
                if settings.DEBUG and request.method == 'POST':
                    raise RuntimeError((""
                    "You called this URL via POST, but the URL doesn't end "
                    "in a slash and you have APPEND_SLASH set. Django can't "
                    "redirect to the slash URL while maintaining POST data. "
                    "Change your form to point to %s%s (note the trailing "
                    "slash), or set APPEND_SLASH=False in your Django "
                    "settings.") % (new_url[0], new_url[1]))

        if new_url == old_url:
            # No redirects required.
            return
        if new_url[0]:
            newurl = "%s://%s%s" % (
                request.scheme,
                new_url[0], urlquote(new_url[1]))
        else:
            newurl = urlquote(new_url[1])
        if request.META.get('QUERY_STRING', ''):
            if six.PY3:
                newurl += '?' + request.META['QUERY_STRING']
            else:
                # `query_string` is a bytestring. Appending it to the unicode
                # string `newurl` will fail if it isn't ASCII-only. This isn't
                # allowed; only broken software generates such query strings.
                # Better drop the invalid query string than crash (#15152).
                try:
                    newurl += '?' + request.META['QUERY_STRING'].decode()
                except UnicodeDecodeError:
                    pass
        // 返回401
        return http.HttpResponsePermanentRedirect(newurl)

4、 在301中资源对应的路径修改为location的url,浏览器缓存301跳转后的请求结果数据
四、解决301的常用思路
1、请求加上时间戳参数,使每次请求都不一样
2、查看是否为realServer返回的301,对url处理,直接

相关文章

网友评论

      本文标题:难忘的301 Moved Permanently (from d

      本文链接:https://www.haomeiwen.com/subject/mretactx.html