jsonp请求url长度过长的替代(ajaxcdr的使用)
问题描述:跨域使用jsonp时url过长的问题
问题解释:
跨域请求时,若用jsonp请求jsonp因是请求的script标签,所以都是get请求,get请求的参数当然是在url后面传过去的了。因浏览器对url有长度限制,所以当提交一篇文章的长度时,就会出现url长度过长的错误。导致请求失败
解决办法:
因之前用过uploadify插件上传文件,他是用flash的跨域提交实现的,所以想到肯定有用flash解决跨域请求的问题, google了“flash ajax插件”查到AJAXCDR:利用 Flash 完美解决 JavaScript 和 AJAX 跨域 HTTP POST/GET 表单请求[原创] 这位博主实现了用flash跨域请求(get,post方式)。
使用:
1.在被请求的站点下的根目录放置安全沙箱策略文件crossdomain.xml,详情
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 }
修改后的文件下载地址:https://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” 的错误” 这个暂时还没有遇到。