問題描述:跨域使用jsonp時url過長的問題
問題解釋:
跨域請求時,若用jsonp請求(詳情見:MVC4 Web Api 與 Ajax交互存在的跨域問題總結)jsonp因是請求的script標簽,所以都是get請求,get請求的參數當然是在url后面傳過去的了。因瀏覽器對url有長度限制,所以當提交一篇文章的長度時,就會出現url長度過長的錯誤。導致請求失敗
解決辦法:
因之前用過uploadify插件上傳文件,他是用flash的跨域提交實現的(基於安全沙箱策略文件crossdomain.xml,詳情:回頭再說:Uploadify跨域上傳原理),所以想到肯定有用flash解決跨域請求的問題, google了“flash ajax插件”查到AJAXCDR:利用 Flash 完美解決 JavaScript 和 AJAX 跨域 HTTP POST/GET 表單請求[原創] 這位博主實現了用flash跨域請求(get,post方式)。
使用:
1.在被請求的站點下的根目錄放置安全沙箱策略文件crossdomain.xml,詳情(Flash安全沙箱和跨域文件)
2.(ajaxcdr包含兩個文件)頁面引入ajaxcdr.js(一定要引入在</body> 結束符之前。否則,在IE下無法生效。也可能提示flash版本問題什么的),在ajaxcdr.js中搜索“var swfName”將其值替換為ajaxcdr.swf的路徑。例如:var swfName = "/Content/ajaxcdr/ajaxcdr.swf";
擴展:
1.ajaxcdr.js文件有個方法定義為$()與Jquery沖突,將其改成ajaxcdr或者其他,並在下邊56行左右調用的時候改成相同的即可
2.該文件定義的發送請求的函數AjaxCrossDomainRequest第三個參數必須是formname,如果沒有參數或者不想用表單的時候就不方便了,以下修改便可實現傳參進去。AjaxCrossDomainRequest方法改寫如下:
1 function AjaxCrossDomainRequest(url, method, formnameordata, callback) { 2 method = js_strtoupper(method); 3 AjaxCrossDomainResname = callback; 4 var contentType = "application/x-www-form-urlencoded"; 5 var body = ''; 6 if (formnameordata==""||formnameordata.indexOf('=') > 0) { body = formnameordata; } //判斷是form或者是data(11=22&22=33) 7 else { 8 var formname = formnameordata; 9 var form = document.forms[formname]; 10 for (var i = 0; i < form.length; i++) { 11 //如果是單選按鈕、復選框、單選下拉框 12 if (form.elements[i].type == "radio" || form.elements[i].type == "checkbox" || form.elements[i].type == "select") { 13 if (form.elements[i].checked && form.elements[i].name != "") { 14 body += encodeURI(form.elements[i].name) + '=' + encodeURI(form.elements[i].value) + '&'; 15 } 16 } 17 //如果是多選下拉框 18 else if (form.elements[i].type == "select-multiple" && form.elements[i].name != "") { 19 for (var sm = 0; sm < form.elements[i].length; sm++) { 20 if (form.elements[i][sm].selected) { 21 body += encodeURI(form.elements[i].name) + '=' + encodeURI(form.elements[i][sm].value) + '&'; 22 } 23 } 24 } 25 //Button、Hidden、Password、Submit、Text、Textarea等文本類型 26 else { 27 if (form.elements[i].name != "") { 28 body += encodeURI(form.elements[i].name) + '=' + encodeURI(form.elements[i].value) + '&'; 29 } 30 } 31 } 32 } 33 var fs = FlashHelper.getFlash(); 34 //fs.loadPolicyFile("http://domain/blah/crossdomain.xml"); 35 if (js_substr(body, -1, 1) == "&"){ 36 body = js_substr(body, 0, -1); 37 } 38 if (method == "GET"){ 39 //GET請求方式 40 var urlget = ""; 41 if (js_substr(url, -1, 1) == "?"){ 42 urlget = url + body; 43 } 44 else if(js_strpos(url, "?") > 0 && js_strpos(url, "=") > 0){ 45 urlget = url + "&" + body; 46 } 47 else { 48 urlget = url + "?" + body; 49 } 50 fs.XmlHttp(urlget, "displayResponse", method, "", contentType); 51 } else { 52 //POST請求方式 53 fs.XmlHttp(url, "displayResponse", method, body, contentType); 54 } 55 }
修改后的文件下載地址:http://files.cnblogs.com/woyouwozai/ajaxcdr.rar
這樣的話 如果要想傳入form表單的參數就傳入一個form的名字,如果不想傳值就把formnameordata參數傳為空(“”),如果是自己拼的參數就參數形如“11=22&22=33”的參數即可。
不過這樣還是遇到問題了當參數中包含“&”就會出現問題例如“11=22&22=3&3”這樣的話就會被解析成三個參數“11,22,3”,這個問題是我在提交包含富文本框的內容是遇到的,當空格連續兩個是源碼就會出現“ ”直接導致500錯誤 最后不得不先把富文本框內編輯的內容中包含"&"的替換成“@@”或其他(templatecontent = templatecontent.replace(/&/g, '@@');) 在后台再替換回來,要不就用fromname提交吧
調用方法:AjaxCrossDomainRequest(url + "/Add", "POST", "Guid=" + $("#mailguid").val() , "alert(AjaxCrossDomainResponse );");
至此才算是可以放心使用了。
還有個朋友在網上說“ 原來的ajaxcdr.js 編碼格式 ANSI編碼,需將此編碼格式更改為UTF-8 編碼格式。否則在IE中會出現fs.XmlHttp “object doesn't support this property or method” 的錯誤” 這個暫時還沒有遇到。