Q9:什么是跨域?什么是JSON?什么是JSONP?解决跨域问题有哪些方法?请结合代码和文字说明。
跨域:因为JavaScript同源策略(一段脚本只能读取来自同一来源的窗口和文档的属性,同一来源指主机名,协议和端口号的组合)的限制,a.com域名下的js无法操作b.com域名下的对象,只要是协议,域名,端口有任何一个不同都被当做是不同的域;
Json(JavaScript Object Notation):一种轻量级的数据交换格式。基于ECMAScript的一个子集。采用完全独立于语言的文本格式,但是也使用了类似类似于C语言家族的习惯,这些特性是json成为理想的交换语言,易于人阅读也易于机器解析和生成。
JSONP(JSON with Padding):是JSON的一种使用模式,可用于解决主流浏览器的跨域数据访问的问题。由于同源策略,一般来说位于server1.example.com的网页无法与不是server1.example.com的服务器沟通,而HTML的<script>元素是一个列外。利用<script>元素这个开放策略,网页可以得到从其他来源动态产生的json自理啊,而这种使用模式就是所谓的JSONP。使用JSONP抓到的并不是JSON,而是任意的JavaScript,用JavaScript直译器执行而不是用JSON解析器解析。
JSONP优点:不想XMLHttpRequest对象实现的ajax请求那样受到同源策略的限制,兼容性好,在古老的浏览器中都可以运行,不需要XMLHttpRequest或ActiveX的支持,并且在请求完毕后可以通过调用callback的方式回传结果。 缺点:只支持GET请求不支持POST等其他类型的HTTP请求,不能解决不同域的两个页面之间如何调用JavaScript调用的问题。
解决跨域问题:(http://www.cnblogs.com/rainman/archive/2011/02/20/1959325.html)
(http://segmentfault.com/a/1190000000718840)
(http://www.cnblogs.com/oneword/archive/2012/12/03/2799443.html)
跨域资源共享(CORS):CORS基本思想使用自定义的http头部让浏览器与服务器进行沟通,从而决定应该是成功还是失败;
绝对路径即要跨域访问的接口地址,服务器端对于CORS的支持主要是通过设置Access-Control-Allow-Origin来进行的。
通过jsonp跨域:JSONP由两部分组成,回调函数(当响应到来时应该在页面中调用的函数)和数据(传入回调函数中的JSON数据);在js中直接用XMLHttpRequest请求不同域上的数据时不可以,但是在页面上引入不同域上的js脚本文件却可以,JSONP正是利用此特性:
Js文件载入成功后会执行在URL参数中指定的函数,并且会把需要的json数据作为参数传入,所以JSONP是需要服务器端的页面进行相应的配合。
输出结果为dosomething([‘a’,’b’,’c’]);
如果页面使用的jQuery:
jQuery会自动生成一个全局函数来替换callback=?中的问好,之后获取到数据后又会自动销毁,实际上就是起一个临时代理函数的作用,$.getJSON方法会自动判断是否跨域,不跨域的话就调用普通的ajax方法,跨域的话则会以异步加载js文件的形式来调用jsonp的回调函数。
通过修改document.domain来跨子域:
将两个页面的document.domain设置成相同的域名,注意设置是有限的,只能把它设置成自身或更高一级的父域,且主域必须相同。
修改document.domain的方法只适用于不同子域的框架间的交互。
使用window.name来进行跨域:即在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每个页面对window.name都有读写的权限,他是持久存在一个窗口载入过的所有页面中。
使用HTML5的window.postMessage方法跨域:window.postmessage(message,targetOrigin)方法是html5 新引进的特性,可以使用它来向其他的window对象发送消息,无论这个window对象是属于同源或不同源。
jQuery:(jsonp方式)
执行此段js时,js向服务器发出了请求:http://192.168.0.5/Web/web1.aspx?jsoncallback=jsonp134505244726&_=1354505244742
而服务器也相应的返回了对象:jsonp1354506338864({“name”:”Zhangsan”,”date”:”2015-8-4”})
此时实现了跨域范文数据的要求。
动态创建script:
利用iframe和location.hash:利用location.hash来进行传值。在url:http://a.com#helloworld中的#helloworld就是lacation.hash,改变hash并不会导致页面刷新,所以可以利用hash值来进行数据传递,但是数据容量是有限的,假设域名a.com下的文件cs1.html要和cnblogs.com域名下的cs2.html传递信息,cs1.html首先创建一个隐藏的iframe,iframe的src指向cnblogs.com域名下的cs2.html页面,这是的hash值可以做参数传递用。cs2.html响应请求后再将通过修改cs1.html的hash值来传递参数(由于两个页面不在同一个域下IE,Chrome不允许修改parent.location.hash的值,所以要借助a.com域名下的一个代理iframe;Firefox可以修改)。同时在cs1.html上加一个定时器,隔离一段时间来判断location.hash的值有没有变化,一点有变化则获取hash值
Q10:请描述一下JavaScript定时器。使用定时器编写一个时钟。
JavaScript是运行于单线程中的,而定时器仅仅是在未来某个时间执行,执行具体时间不能被保证,在页面的生命周期中不同的时间有可能有其他代码在控制JavaScript的里进程。浏览器只是负责排序,纸牌某个代码在某个时间点运行;定时器对队列的工作方式:当特定的时间过去,将代码插入,添加到队列并不以为会马上执行,只能说会尽快执行,设定时间到达时只是被加入到队列中,如果这个时间点队列是空的则会被马上执行;
setInterval()方法会不停的调用函数,直到clearInterval()被调用或窗口被关闭。由setInterval()返回的ID值可用作clearInterval()方法的参数。关于重复定时器可以使用setTimeout来重复创建定时器,也可以直接用setInterval,使用setInterval创建的定时器确保了定时器规则的插入队列中这个方法在于代码可能在再次添加到队列之前还没有完成执行,可能寻到定时器重复运行好几次而中间没有停顿,现在搜索殷勤能避免这个问题,当使用setInterval时,仅当没有定时器的任何其他代码时,才将定时器代码添加到队列中来确保定时器代码加入到队列的时间间隔是指定的间隔,所以使用setInterval会存在两个问题:某些间隔会被跳过;多个定时器的代码执行间隔可能会比预期的小。为避免此问题使用链式setTimeout调用:
倒记计时器:timename=setTimeout(“function();”,delaytime);只作用一次
循环计时器:timename=setInterval(“function();”,delaytime);反复作用
获取焦点:if(“mid” == document.activeElement.id){alert();}”mid”表单对应的ID