JavaWeb-GET请求中URL的最⼤长度限制(附:解决⽅案)今天在写⼀个 PHP 相应 JSOUP 请求的功能时,发现当 URL 中包含的请求参数过长时会返回 414 错误。
浏览器
1、IE
IE浏览器(Microsoft Internet Explorer) 对RL长度限制是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
url编码和utf8区别
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/requestLimitssetting.<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 = Item(newsId + "_title");
var content = Item(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");
* Item("key");
* */
if (!window.sessionStorage) {
window.sessionStorage = {
getItem: function(sKey) {
if (!sKey || !this.hasOwnProperty(sKey)) {
return null;
}
return place(new RegExp("(?:^|.*;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*"), "$1"));        },
key: function(nKeyId) {
return place(/\s*\=(?:.(?!;))*$/, "").split(/\s*\=(?:[^;](?!;))*[^;]?;\s*/)[nKeyId]);
},
setItem: function(sKey, sValue) {
if (!sKey) {
return;
}
this.length = kie.match(/\=/g).length;
},
length: 0,
removeItem: function(sKey) {
if (!sKey || !this.hasOwnProperty(sKey)) {
return;
}
this.length--;
},
hasOwnProperty: function(sKey) {
return (new RegExp("(?:^|;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).kie);
}
};
window.sessionStorage.length = (kie.match(/\=/g) || window.sessionStorage).length;
}
Ps:将这个插件引⼊到⽤到sessionStorage的地⽅,就不怕IE不⽀持啦!

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。