• cookie过大导致request 400 错误研究


    问:get请求太长报400的错误,如何解决?生成系统中经常偶现此问题
    问:get请求URL的长度是谁限制的?
    问:每一个cookie的value的大小还是同域下cookie的个数做的限制?

    现象:出现 400 Bad request

    在这里插入图片描述

    状态码400:客户端请求有语法错误,不能被服务器所理解。

    问题:request header过大

    一个HTTP请求报文由请求行(request line)、请求头部(header)、空行和请求体4个部分组成。
    在这里插入图片描述
    谁对request header 大小做限制?

    在HTTP规范RFC-2616中有这样一段描述:

    The HTTP protocol does not place any a priori limit on the length of a URI. Servers MUST be able to handle the URI of any resource they serve, and SHOULD be able to handle URIs of unbounded length if they provide GET- based forms that could generate such URIs. A server SHOULD return 414 (Request-URI Too Long) status if a URI is longer than the server can handle (see section 10.4.15).
    Note: Servers ought to be cautious about depending on URI lengths above 255 bytes, because some older client or proxy implementations might not properly support these lengths.

    HTTP协议没有对传输的数据大小进行限制,HTTP协议规范也没有对URI长度进行限制,只是说如果server无法处理太长的URI,可以通过返回414状态码。

    规范中虽然未对GET请求的长度做出明确的规定,但是在浏览器和应用服务器中对GET请求却做出限制或者相关的可配置:

    • Chrome:对Google浏览器URL的最大长度为8182个字符。
    • IE:对IE浏览器URL的最大长度为2083个字符。若超出这个数字,提交按钮没有任何反应。
    • Firefox:对Firefox浏览器URL的最大长度为65536个字符。
    • Safari: 对Safari浏览器URL的最大长度为80000个字符。
    • Apache能接受url长度限制为8192字符
    • nginx可以通过修改配置来改变url请求串的url长度限制:
      • client_header_buffer_size 默认值:1k
      • large_client_header_buffers默认值:4 8k

    浏览器限制更多还是服务器限制更多?

    实验分析

    实验结论:浏览器允许的request header大小一般情况比Nginx服务器允许的大

    测试方式:设置同样大小的cookie,通过浏览器直接访问服务器与通过浏览器先访问到Nginx再代理到服务器做对比得出。

    const http = require('http');
    const url = require('url');
    const fs = require('fs-extra');
    
    const server = http.createServer(async (req, res) => {
        if (req.url === '/index.html') {
            console.log(req.headers);
            const html = await fs.readFile('./index.html', 'utf8');
            const cookieArr = [];
            for (let i = 0; i < 10; i++) {
                cookieArr.push(`cookie${i}=${Array.from({ length: 80 }, (v, i) => 'abcdefghijklmnopq' + i).join('')}value${i}; `);
            }
            res.writeHead(200, {
                'Content-Type': 'text/html',
                'Set-Cookie': cookieArr
            });
            res.end(html);
        }
        if (req.url.startsWith('/postMethod')) {
            console.log('post');
            res.end('post');
        }
    });
    server.listen('3000', '127.0.0.1', () => {
        console.log('server runing...');
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    结论

    过浏览器直接访问服务器的没有问题。
    在这里插入图片描述

    通过Nginx转发的存在问题

    在这里插入图片描述

    修改Nginx配置
    • client_header_buffer_size
      client_header_buffer_size size;
      Default: client_header_buffer_size 1k;
      Context: http, server

    • large_client_header_buffers
      Syntax: large_client_header_buffers number size;
      Default: large_client_header_buffers 4 8k;
      Context: http, server

    解决方案总结:

    1. cookie要设置合理,不能太大,个数不能太多
    2. 合理设置时效性,max-age,expires
    3. get请求参数过长,出现参数丢失情况
    4. Nginx上修改允许request header头大小配置,很明显,当前的ng默认配置已不能满足需求。
    5. 临时解决方案:让用户清除cookie。影响:用户需要重新登录
  • 相关阅读:
    为什么都说测试岗是巨坑,趁早跳出去?10年测试人告诉你千万别上当了...
    java计算机毕业设计学生信息管理系统源程序+mysql+系统+lw文档+远程调试
    学习java的day02
    【FI】采购预付款管理报错“字段BSEG-EBELP在屏幕SAPMF05A0304上不存在”
    使用QianWei网站源码配合cpolar,发布本地音乐分享网站
    五、JAVA基本数据类型
    无线网络、HTTP缓存、IPv6
    Java线程stop,sleep,yield,join
    稀疏矩阵转十字链表
    SQL每日一练(牛客新题库)——第10天:排序检索数据
  • 原文地址:https://blog.csdn.net/yexudengzhidao/article/details/134020229