面试被虐系列_前端开发篇_Ajax
2017-03-20 19:27
316 查看
题目:请阐述在面对Ajax跨域问题的时候,你是如何处理的,同时对其原理进行阐述。
思考:
在当今的互联网世界中,Ajax可以说是极其重要的一项技术,该技术的出现,可谓是大大的提高了页面应用程序开发人员的效率,与此同时也极大提升了用户再使用web应用程序的体验。但是在底层的实现机制上,因为安全的考虑,浏览器本身并不支持Ajax直接进行跨域访问。但是在实际的开发过程中,或多或少的,我们都会遇到需要跨域处理的情况。
这里我尽量尝试阐述清除几种实现跨域请求的方式,以及工作原理。和之前的文章一样,依然借鉴了网络上一些前辈的工作,本人也结合自己的实际经验,对其中一些处理方式进行解读。欢迎大家吐槽,拍砖和交流。
jsonp的使用:
深入,在jquery中其实本质的实现也是利用script和回调函数来实现
思考:
在当今的互联网世界中,Ajax可以说是极其重要的一项技术,该技术的出现,可谓是大大的提高了页面应用程序开发人员的效率,与此同时也极大提升了用户再使用web应用程序的体验。但是在底层的实现机制上,因为安全的考虑,浏览器本身并不支持Ajax直接进行跨域访问。但是在实际的开发过程中,或多或少的,我们都会遇到需要跨域处理的情况。
这里我尽量尝试阐述清除几种实现跨域请求的方式,以及工作原理。和之前的文章一样,依然借鉴了网络上一些前辈的工作,本人也结合自己的实际经验,对其中一些处理方式进行解读。欢迎大家吐槽,拍砖和交流。
jsonp的使用:
/***** 方式一:jQuery jQuery中提供了封装的jsonp的请求,在使用的时候,我门可以像使用正常ajax请求一样。 只不过需要将dataType设置为"jsonp",然后添加一个jsonp参数,其值为"callback",即可使用。 *****/ $("#something").click(function () { $.ajax({ url: 'http://www.baidu.com/home/somejsonp', dataType: "jsonp", jsonp: "callback", success: function (data) { console.log(data) } }) }) /***** 方式二:手动使用script标签的src获取 如果不借助jQuery直接使用jsonp来手动实现跨域访问,可以使用以下方式 借助于script标签的src来发起请求,采用callback回调函数来接收具体的数据。 如果没有回调函数,则浏览器回直接将返回的数据作为js脚本执行,并出现报错。 如果接口返回的数据是{"city":"北京","ID":"1000"},则发起请求之后回直接打印出结果。 *****/ function CreateScript(src) {//动态创建script标签 $("<script><//script>").attr("src", src).appendTo("body") } function callback(json) {//定义回调函数,处理返回数据 console.log(json) } $("#something").click(function () {//发起请求 CreateScript("http://www.baidu.com/home/somejsonp?callback=callback") }) /***** 方式三:使用postMessage postMessage是h5的一个新功能之一,这里可以使用iframe来完成跨域的数据交换。 *****/ //iframe内部脚本 var message = 'date';<br>if (parent.document.getElementById('iframe')) { //捕获iframe var iframe = parent.document.getElementById('iframe').contentWindow; //发送消息 parent.postMessage(message, "*"); } //iframe外部脚本 window.addEventListener('message',function(e){ },false); /***** 方式四:利用最新的HTML5中提供的XMLHTTPREQUEST Level2(及XHR2)实现跨域访问。 IE10以下的浏览器不支持,具体的方式如下: *****/ //在服务端响应的header新增如下属性即可实现。 header("Access-Control-Allow-Origin:*"); /*星号表示所有的域都可以接受,*/ header("Access-Control-Allow-Methods:GET,POST");
深入,在jquery中其实本质的实现也是利用script和回调函数来实现
/***** 在最新的jQuery开发版源码中,第9663行---9740行,是对jsonp格式请求的具体处理,具体的源码如下: *****/ // Detect, normalize options and install callbacks for jsonp requests jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { var callbackName, overwritten, responseContainer, jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? "url" : typeof s.data === "string" && ( s.contentType || "" ) .indexOf( "application/x-www-form-urlencoded" ) === 0 && rjsonp.test( s.data ) && "data" ); // Handle iff the expected data type is "jsonp" or we have a parameter to set if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { // Get callback name, remembering preexisting value associated with it callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback; // Insert callback into url or form data if ( jsonProp ) { s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); } else if ( s.jsonp !== false ) { s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; } // Use data converter to retrieve json after script execution s.converters[ "script json" ] = function() { if ( !responseContainer ) { jQuery.error( callbackName + " was not called" ); } return responseContainer[ 0 ]; }; // Force json dataType s.dataTypes[ 0 ] = "json"; // Install callback overwritten = window[ callbackName ]; window[ callbackName ] = function() { responseContainer = arguments; }; // Clean-up function (fires after converters) jqXHR.always( function() { // If previous value didn't exist - remove it if ( overwritten === undefined ) { jQuery( window ).removeProp( callbackName ); // Otherwise restore preexisting value } else { window[ callbackName ] = overwritten; } // Save back as free if ( s[ callbackName ] ) { // Make sure that re-using the options doesn't screw things around s.jsonpCallback = originalSettings.jsonpCallback; // Save the callback name for future use oldCallbacks.push( callbackName ); } // Call if it was a function and we have a response if ( responseContainer && jQuery.isFunction( overwritten ) ) { overwritten( responseContainer[ 0 ] ); } responseContainer = overwritten = undefined; } ); // Delegate to script return "script"; } } );
相关文章推荐
- 从零开始学_JavaScript_系列(26)——只需要前端知识的ajax教程
- 前端面试之Ajax和Json
- 破解前端面试系列(3):如何搞定纸上代码环节?
- 前端面试系列之----补充问题集合
- 前端面试系列之---DOM操作 BOM
- 前端开发面试总结系列一
- 合格前端系列第九弹-前端面试那些事
- 破解前端面试(80% 应聘者不及格系列):从闭包说起
- 破解前端面试系列(3):如何搞定纸上代码环节?
- 【前端面试】谈谈你对jQuery中的ajax方法的了解
- 9 HTML&JS等前端知识系列之Ajax post请求带有token向Django请求
- 面试被虐系列_算法分析篇_排序算法
- 面试被虐系列_设计模式篇_单例模式
- 破解前端面试(80% 应聘者不及格系列):从 DOM 说起
- 面试被虐系列_基础数据结构篇_C#集合接口_3
- Web前端面试指导(二十九):Ajax 是什么? 如何创建一个Ajax?
- 前端资源系列-教程&模块化/规范化/工程化/优化&工具/调试&值得关注的博客/Git&面试资源汇总
- 面试被虐系列_基础数据结构篇_C#集合接口_1
- 前端面试系列之---javascript基础和数据类型
- 破解前端面试(80% 应聘者不及格系列):从 闭包说起