ajax面试题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ajax面试题相关的知识,希望对你有一定的参考价值。
一、ajax及过程
创建xmlHttpRequest对象,调用open方法,调用send方法,监听xmlHttpRequest的onReadyStateChange方法
var oAjax = new XMLHttpRequest();//创建ajax对象 xhr.open("post","test.php",true); xhr.send(); xhr.onreadystatechange = function() { if(xhr.readyState == 4 && xhr.status == 200) { alert(xhr.responseText); } }
二、tcp连接过程
1.tcp客户端的流程:
socket()——>connect()——>write() or read() 完成交互——> close()
其中,connnect发起主动连接;客户端不需要绑定端口,需要绑定服务器端的ip,(udp里面是数据DatagramPaket自己封装ip和端口)系统会进行自动分配
2.tcp服务器端的流程:
socket()——>bind()——>listen()——>accept()——>read() or write()完成交互——>close()
其中,bind()绑定ip和端口;listen()则把一个未连接的套接口转换成一个被动套接口(创建一个套接口后,被假设为一个主动套接口);accept()等待接收;close()关闭套接口,具体的说,close操作只是使得相应套接字的引用计数减一,只有当计数减少为0的时候,才会触发tcp客户端向服务器发送终止连接请求(主要考虑多线程)。
三、跨域通信
详细可以参见http://www.cnblogs.com/greatluoluo/p/6273463.html
跨域问题的由来:
跨域是由浏览器的同源策略引起的,同源是指:域名、协议、端口相同。不同源的客户端脚本(javascript、ActionScript)在没明确授权的情况下,不能读写对方的资源。
备注:
1)域名和该域名对应的ip之间,也是不允许访问的。
2)主域名和子域名之间,如baidu.com和youxi.baidu.com,也是不允许访问的
解决跨域问题,可选的方案有:
1.使用iframe;
iframe实现跨域方法较多,一种方法是基于window.name的特性。
window 对象的name属性是一个很特别的属性,当该window的location变化,然后重新加载,它的name属性可以依然保持不变。那么我们可以在页面 A中用iframe加载其他域的页面B,而页面B中用JavaScript把需要传递的数据赋值给window.name,iframe加载完成之后(iframe.onload),页面A修改iframe的地址,将其变成同域的一个地址,然后就可以读出iframe的window.name的值了(因为A中的window.name和iframe中的window.name互相独立的,所以不能直接在A中获取window.name,而要通过iframe获取其window.name)。这个方式非常适合单向的数据请求,而且协议简单、安全。不会像JSONP那样不做限制地执行外部脚本。
2.使用图片信标(可以传递的信息有限)
3.使用jsonp
需要对服务器具有完全控制
原理:通过script标签引入的js不收同源策略的限制,而XmlHttpRequest 对象受到同源策略的影响,可以加载跨域服务器上的脚本,用 JSONP 获取的不是 JSON 数据,而是可以直接运行的 JavaScript 语句。
JSONP通常的使用方法有两种:jQuery的ajax和原生script标签实现,需要注意的是,尽管使用jQuery的ajax实现表面看上去和ajax的调用方法很像,事实上由于二者的实现原理不同, JSONP 实现的跨域调用不是通过 XmlHttpRequset 对象,而是通过 script
标签,所以在实现原理上,JSONP 和 Ajax 已经一点关系都没有了。看上去形式相似只是由于 jQuery 对 JSONP 做了封装和转换。
原生js实现jsonp的案例:
<script src = ‘http://localhost:3001/ajax/deal?callback=jsonpCallback&name=chiaki&id=3001&_=1473164876032‘></script>
服务器端代码:
app.get(‘/jsonServerResponse‘, function(req, res) { var cb = req.query.jsonp //这里得到请求页面的回调函数 console.log(cb) //思考一下为什么这里要这样写 var data = ‘var data = {‘ + ‘name: $("#name").val() + " - server 3001 jsonp process",‘ + ‘id: $("#id").val() + " - server 3001 jsonp process"‘ + ‘};‘ var debug = ‘console.log(data);‘ //打印var data=""; var callback = ‘$("#submit").click(function() {‘ + data + cb + ‘(data);‘ + debug + ‘});‘ res.send(callback) //返回的是一个点击按钮的事件 res.end() })
jsonp的不足:
- 只能使用 GET 方法发起请求,不安全,这是由于
script
标签自身的限制决定的。 - 不能很好的发现错误,并进行处理。与 Ajax 对比,由于不是通过 XmlHttpRequest 进行传输,所以不能注册 success、 error 等事件监听函数。
4.使用 CORS 实现跨域调用
需要对服务器端能进行控制
原理:CORS的思想,就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功,还是应该失败。
Cross-Origin Resource Sharing(CORS)跨域资源共享是一份浏览器技术的规范,提供了 Web 服务从不同域传来沙盒脚本的方法,以避开浏览器的同源策略,是 JSONP 模式的现代版。与 JSONP 不同,CORS 除了 GET 要求方法以外也支持其他的 HTTP 请求。 CORS 一般用XMLHttpRequest,这种方式的错误处理比 JSONP 要来的好。另一方面,JSONP 可以在不支持 CORS 的老旧浏览器上运作。现代的浏览器都支持 CORS。需要配置服务器端的Access-Control-Allow-Origin,Access-Control-Allow-Headers,Access-Control-Allow-Methods 等属性
假设 服务器 3000 上的请求页面向 服务器 3001 发送请求为例。
服务器 3000 上的请求页面 JavaScript 不变,服务器 3001上对应的处理函数:
app.post(‘/cors‘, function(req, res) { res.header("Access-Control-Allow-Origin", "*"); //设置请求来源不受限制 res.header("Access-Control-Allow-Headers", "X-Requested-With"); res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS"); //请求方式 res.header("X-Powered-By", ‘ 3.2.1‘) res.header("Content-Type", "application/json;charset=utf-8"); var data = { name: req.body.name + ‘ - server 3001 cors process‘, id: req.body.id + ‘ - server 3001 cors process‘ } console.log(data) res.send(data) res.end() })
5.使用服务器代理
在数据提供方没有提供对JSONP协议,也没有对其它域开放访问权限,我们可以通过server proxy的方式来抓取数据。例如当baidu.com域下的页面需要请求google.com下的资源文件getUsers.php时,直接发送一个指向google.com/getUsers.php的Ajax请求肯定是会被浏览器阻止。这时,我们在Baidu.com下配一个代理,然后把Ajax请求绑定到这个代理路径下,例如baidu.com/proxy/,然后这个代理发送HTTP请求访问google.com下的getUsers.php,跨域的HTTP请求是在服务器端进行的(服务器端没有同源策略的限制),客户端并没有产生跨域的Ajax请求。这个跨域方式下不需要和目标资源签订协议,带有侵略性。
以上是关于ajax面试题的主要内容,如果未能解决你的问题,请参考以下文章