JavaWeb – GET 请求中 URL 的最大长度限制(附:解决方案)[通俗易懂]

JavaWeb – GET 请求中 URL 的最大长度限制(附:解决方案)[通俗易懂]今天在写一个PHP相应JSOUP请求的功能时,发现当URL中包含的请求参数过长时会返回414错误。浏览器1、IEIE浏览器(MicrosoftInternetExplorer)对URL长度限制是2083(2K+53),超过这个限制,则自动截断(若是form提交则提交按钮不起作用)。中文字符的话只有2083/9=231个字符。2、Firefoxfi…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

今天在写一个 PHP 相应 JSOUP 请求的功能时,发现当 URL 中包含的请求参数过长时会返回 414 错误。

 

浏览器


1、IE

IE浏览器(Microsoft Internet Explorer) 对URL长度限制是2083(2K+53),超过这个限制,则自动截断(若是form提交则提交按钮不起作用)。中文字符的话只有2083/9=231个字符。

2、Firefox

firefox(火狐浏览器)的url长度限制为 65 536字符,但实际上有效的URL最大长度不少于100,000个字符。

3、Chrome

chrome(谷歌)的url长度限制超过8182个字符返回本文开头时列出的错误。支持的最大中文字符只有8182/9=909个。

4、Safari

Safari的url长度限制至少为 80 000 字符。

5、Opera

Opera 浏览器的url长度限制为190 000 字符。Opera 9 地址栏中输入190 000字符时依然能正常编辑。

 

 

服务器


1、Apache

Apache能接受url长度限制为8192字符。

2、IIS

Microsoft Internet Information Server(IIS)能接受url长度限制为16384个字符。
这个是可以通过修改的(IIS7)

configuration/system.webServer/security/requestFiltering/requestLimits@maxQueryStringsetting.<requestLimits maxQueryString="length"/>

3、Perl HTTP::Daemon

Perl HTTP::Daemon 至少可以接受url长度限制为8000字符。Perl HTTP::Daemon中限制HTTP request headers的总长度不超过16384字节(不包括post,file uploads等)。但当url超过8000字符时会返回413错误。

这个限制可以被修改,在Daemon.pm查找16×1024并更改成更大的值。

4、Ngnix

可以通过修改配置来改变url请求串的url长度限制。

client_header_buffer_size 默认值:client_header_buffer_size 1k
large_client_header_buffers默认值 :large_client_header_buffers 4 4k/8k

 

解决方案


答案:sessionStorage

背景

有个需求是对资讯进行预览(类似于发博客前预览下效果这样),一种很容易想到的简单办法是将预览的内容(如标题和正文)通过get请求传递到预览页中,js代码如下:

function previewNews(){
    var action = "XXXX" ;
    // 拿到页面中的标题和正文    
    var title = $("#title").val();
    var content = $("#content").val(); 

    var url = action+ "?title=" + encodeURIComponent(title) + "&content=" + encodeURIComponent(content); 
    window.open(url);//打开拼接后的url
}

这种方法在标题和正文字数不多的情况下是没有问题的。but问题是,资讯的正文字数却经常出乎意料地很长。多长呢?长到预览页面load啊load啊就是load不出来。查了查,这是因为浏览器或者服务器对url有长度限制(很多人包括我自己误解为是HTTP get方法对参数的限制,其实不是)。百度来的资料如前面所说的大小限制。

而且,中文是以urlencode后的编码形式进行传递。如果浏览器的编码为UTF8的话,一个汉字最终编码后的字符长度为9个字符。(这句话也是百度来的,未经证实)这么算算,对于IE浏览器来说,标题和正文加起来最多能输入231个中文,超过了就完蛋。那么通过get方式传递参数预览这样的解决办法就变得毫无用处,因为资讯一般来说至少是三五百字的,必须寻找替代方案。

 

替代方案

想到的两种替代方案如下:

  1. 将预览内容post到服务端,根据一个唯一标识生成缓存(有效时间5分钟),将唯一标识返回到前端,前端通过get方式传递唯一标识请求预览逻辑,拿到缓存的内容后渲染到页面。需要说明的是这里的缓存必须是分布式的。
  2. 通过H5的会话缓存sessionStorage将预览内容存储在浏览器,打开预览页后从sessionStorage中拿到内容就可以渲染出页面了。

Ps:第一个解决方案需要用到分布式缓存,而我们的应用目前还没有引入分布式缓存,为了一个预览功能引入分布式缓存无论从时间成本来说还是其他成本,都不划算。怎么算都是使用sessionStorage更加便捷。

 

走近 sessionStorage

sessionStorage,顾名思义,是浏览器基于session的一种本地存储方式。这些数据只有在同一个会话中的页面才能访问并且当会话结束后数据也随之销毁。因此sessionStorage并不是一种持久化的本地存储。与之相对应的另一种H5本地存储技术localStorage却是一种持久化的本地存储方式。结合资讯预览的需求,明显sessionStorage更适用。虽然之前并没有用过sessionStorage,但我还是义无反顾地将它应用在了这个需求上。其实它的使用方法还算挺简单的:

function previewNews(){
    var action = "XXX" ;

    var newsId = $("#id").val();//资讯的唯一标识
    var title = $("#title").val();
    var content = $("#content").val(); 
    //通过setItem方法存储value
    sessionStorage.setItem(newsId+"_title",title);
    sessionStorage.setItem(newsId+"_content",content);

    var url = action+ "?newsId=" + newsId; 
    window.open(url);
}

预览页取内容时这样写:

$(document).ready(function() {
    var newsId = $("#newsId").val();
    //通过getItem方法获取value
    var title = sessionStorage.getItem(newsId + "_title");
    var content = sessionStorage.getItem(newsId + "_content");

    $("#news_title").html(title);
    $("news_content").html(content);
});

简单的几行代码,解决了因为内容过长不能预览的问题。但是别慌,还有一个潜在的问题需要解决,那就是,sessionStorage对IE的支持不够好。换句话说,如果用户使用的是IE浏览器,那么还是会打不开预览页。怎么办呢?不用慌,早已经有人帮我们解决好了,网上一搜就有了。简单说,如果是IE浏览器,那么我们引入一个js插件,这个插件用cookie重写了sessionStorage的几个方法(setItem、getItem等),代码一看便知:

插件名:sessionStorage.js

/**
 *补充不支持sessionStorage的浏览器使用cookie代替
 * 使用:
 * sessionStorage.setItem("key","value");
 * sessionStorage.getItem("key");
 * */
if (!window.sessionStorage) {
    window.sessionStorage = {
        getItem: function(sKey) {
            if (!sKey || !this.hasOwnProperty(sKey)) {
                return null;
            }
            return unescape(document.cookie.replace(new RegExp("(?:^|.*;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\$&") + "\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*"), "$1"));
        },
        key: function(nKeyId) {
            return unescape(document.cookie.replace(/\s*\=(?:.(?!;))*$/, "").split(/\s*\=(?:[^;](?!;))*[^;]?;\s*/)[nKeyId]);
        },
        setItem: function(sKey, sValue) {
            if (!sKey) {
                return;
            }
            document.cookie = escape(sKey) + "=" + escape(sValue) + "; path=/";
            this.length = document.cookie.match(/\=/g).length;
        },
        length: 0,
        removeItem: function(sKey) {
            if (!sKey || !this.hasOwnProperty(sKey)) {
                return;
            }
            document.cookie = escape(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/";
            this.length--;
        },
        hasOwnProperty: function(sKey) {
            return (new RegExp("(?:^|;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\$&") + "\\s*\\=")).test(document.cookie);
        }
    };
    window.sessionStorage.length = (document.cookie.match(/\=/g) || window.sessionStorage).length;
}

Ps:将这个插件引入到用到sessionStorage的地方,就不怕IE不支持啦!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/172523.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Java NIO读书笔记

    Java NIO读书笔记

  • index() 方法返回指定元素相对于其他指定元素的 index 位置。

    index() 方法返回指定元素相对于其他指定元素的 index 位置。

    2021年10月18日
  • java中sqrt函数的详解[通俗易懂]

    java中sqrt函数的详解[通俗易懂]一、原理:牛顿迭代法具体解释:牛顿迭代法求平方根那我们怎么用牛顿迭代法呢?首先要明白,牛顿迭代法求的是函数和X轴的交点的横坐标,也就是我们说的根1)那么第一步就是构建曲线了。假设有一个数c,我们求它的平方根x,那么有一个等式,x^2=c;挪到一边就是求f= x^2-c的根x2)带入上面的公式也就是 3)既然是个迭代,那么

  • 手背静脉识别的图像处理算法

    手背静脉识别的图像处理算法手背静脉识别的图像处理算法题目内容及要求手背静脉识别技术作为一种全新的特征识别技术,相比于传统的生物识别技术(如指纹识别)具有许多明显的优势,然而对于该技术的研究尚处于刚刚起步阶段,使用计算机来直接进行静脉识别与身份匹配仍然较为困难,为了方便后续特征识别,提高静脉识别的准确度和优越性,有必要对获取的静脉图像进行一系列处理,得到静脉的骨架结构。题目主要要求为:1.对采集图像进行背景去除,取得…

  • tomcat日志设置与详解

    tomcat日志设置与详解1&nbsp;&nbsp;&nbsp;Tomcat日志概述Tomcat日志信息分为两类:一是运行中的日志,它主要记录运行的一些信息,尤其是一些异常错误日志信息。二是访问日志信息,它记录的访问的时间,IP,访问的资料等相关信息。2&nbsp;&nbsp;&nbsp;Tomcat日志配置2.1&nb…

  • vue和layUi对比

    vue和layUi对比vue和layUi对比vue(angular,react)这些框架会负责数据和视图的绑定,数据变了,视图自动更新,视图发生事件,也会更新数据,很省事。layui(bootstrap,extjs)这类库,感觉不是框架,而是组件库,会提供一些组件(比如表格,树),只提供外观和行为,不提供和数据的绑定,数据变了,你负责刷新;视图变了,你自己获取数据。vue的界面库elementui和layui都是组件库,区别就是数据和视图是不是关联的。layui其实更偏向与后端开发人员使用,在服务端页面上有非常好的效果

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号