[转载]jsonp请求url长度过长的替代(ajaxcdr的使用) – 我有我在 – 博客园.
问题描述:跨域使用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方法改写如下:
function AjaxCrossDomainRequest(url, method, formnameordata, callback) { method = js_strtoupper(method); AjaxCrossDomainResname = callback; var contentType = "application/x-www-form-urlencoded"; var body = ''; if (formnameordata==""||formnameordata.indexOf('=') > 0) { body = formnameordata; } //判断是form或者是data(11=22&22=33) else { var formname = formnameordata; var form = document.forms[formname]; for (var i = 0; i < form.length; i++) { //如果是单选按钮、复选框、单选下拉框 if (form.elements[i].type == "radio" || form.elements[i].type == "checkbox" || form.elements[i].type == "select") { if (form.elements[i].checked && form.elements[i].name != "") { body += encodeURI(form.elements[i].name) + '=' + encodeURI(form.elements[i].value) + '&'; } } //如果是多选下拉框 else if (form.elements[i].type == "select-multiple" && form.elements[i].name != "") { for (var sm = 0; sm < form.elements[i].length; sm++) { if (form.elements[i][sm].selected) { body += encodeURI(form.elements[i].name) + '=' + encodeURI(form.elements[i][sm].value) + '&'; } } } //Button、Hidden、Password、Submit、Text、Textarea等文本类型 else { if (form.elements[i].name != "") { body += encodeURI(form.elements[i].name) + '=' + encodeURI(form.elements[i].value) + '&'; } } } } var fs = FlashHelper.getFlash(); //fs.loadPolicyFile("http://domain/blah/crossdomain.xml"); if (js_substr(body, -1, 1) == "&"){ body = js_substr(body, 0, -1); } if (method == "GET"){ //GET请求方式 var urlget = ""; if (js_substr(url, -1, 1) == "?"){ urlget = url + body; } else if(js_strpos(url, "?") > 0 && js_strpos(url, "=") > 0){ urlget = url + "&" + body; } else { urlget = url + "?" + body; } fs.XmlHttp(urlget, "displayResponse", method, "", contentType); } else { //POST请求方式 fs.XmlHttp(url, "displayResponse", method, body, contentType); } }
修改后的文件下载地址:http://files.cnblogs.com/woyouwozai/ajaxcdr.rar
这样的话 如果要想传入form表单的参数就传入一个form的名字,如果不想传值就把formnameordata参数传为空(“”),如果是自己拼的参数就参数形如“11=22&22=33”的参数即可。
调用方法: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” 的错误” 这个暂时还没有遇到。