JavaWeb - GET 请求中 URL 的最大长度限制(附:解决方案)
今天在寫一個 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方式傳遞參數預覽這樣的解決辦法就變得毫無用處,因為資訊一般來說至少是三五百字的,必須尋找替代方案。
替代方案
想到的兩種替代方案如下:
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方法存儲valuesessionStorage.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方法獲取valuevar 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不支持啦!
總結
以上是生活随笔為你收集整理的JavaWeb - GET 请求中 URL 的最大长度限制(附:解决方案)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数学建模美赛历年优秀论文(O奖)
- 下一篇: MATLAB 软件安装与无法打开问题