关于本地调试Ajax产生的问题及引发的思考
- Ajax
- Ajax问题之一——打开chrome浏览器访问页面,报错:Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.(大致意思是:Cross origin请求只支持的协议有:http,data, chrome, chrome-extension, https.)
- 问题之二——如果open()中的url访问的是一个绝对路径,就会报错,报错信息如下:No 'Access-Control-Allow-Origin' header is present on the requested resource.(浏览器的跨域行为违反了安全)
- Ajax问题之三——(采用配置chrome达解决本地跨域问题)能够读取文件,但是ajax对象实例的status=0?
- 关于本例中Ajax的demo所引发的思考
Ajax
Ajax(Asynchronous JavaScript + XML),直译过来就是异步 JavaScript和XML。
Ajax是什么
是一种无需刷新页面就能够从服务器取得数据的一种方法。
Ajax干什么
Web的运作原理:一次HTTP请求对应一个页面。
如果没有Ajax,一次HTTP请求从服务器端读取了文件或数据后,再将获取的数据写进html里,需要整个页面刷新,出现浪费资源、网络不好的情况下会影响用户体验等一系列问题。Ajax的运用,可以使页面在需要的时候局部刷新,让用户仍然停留在当前页面,其实局部已经发送了HTTP请求并获得了数据再来进行更新。最直观的感受就是——提高用户体验。
参考:阮一峰——Ajax
参考书籍:《JavaScript高级程序设计(第三版)》
Ajax流程
- 创建Ajax对象
- 连接服务器
- 发送请求
- 接收相应结果
负责Ajax运作的核心对象是XMLHttpRequest(XHR)对象,在较低版本(主要是:IE6-IE9等),采用的是ActiveXObject对象实现的。
Ajax代码实现
var getbtn = document.getElementById("getAjax");
getbtn.onclick = function () {
var ajax;
if (window.XMLHttpRequest) {
ajax = new XMLHttpRequest();
//1-1、普通版本的创建Ajax对象
} else {
ajax = new ActiveXObject('Microsoft.XMLHTTP');
//1-2、低版本的创建Ajax对象
}
ajax.open('GET', './Ajax.txt', true);
//2、连接服务器,open方法接收三个参数:请求类型,url,是否异步的Boolean
ajax.send(null);
//3、发送请求,如果无数据请求,一定要写null
ajax.onreadystatechange = function () {
if ( ajax.readyStatus == 4 && ajax.status == 200) {
/*
一、ajax对象的readyStatus属性值为0到4,
分别对应不同ajax请求中的状态,4代表过程结束,
但不一定是请求成功的。
二、ajax对象的status属性值代表着请求的结果,相应HTTP的状态,
可以将“200”作为请求成功的标志,其余均有各自代表的意思。
*/
console.log(ajax.responseText);
/*
ajax对象的responseText属性表示作为相应主体被返回的文本。
*/
}else{
alert("error");
}
};
}
Ajax问题之一——打开chrome浏览器访问页面,报错:Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.(大致意思是:Cross origin请求只支持的协议有:http,data, chrome, chrome-extension, https.)
当我们点击报错信息里的页面的时候,发现是可以访问到这个文件信息的。
我猜测,大概率是访问地址的file这部分有点错误吧。下面进行验证:
我们发现ajax.html的window.location属性中有我们熟悉的字眼——protocol,并且显示的是“file:”,与报错信息的内容基本上吻合。
说明chrome浏览器不支持file协议。
解决方法:
- 如果换成Firefox浏览器,就能够正常运行。
- 采用虚拟机运行html文件,模拟环境,用localhost访问即可,此时的protocol:“http:”
- 配置chrome,使其支持file协议。
设置Chrome的快捷方式的属性,在“目标”后面加上–allow-file-access-from-files,注意前面有个空格,重新打开Chrome即可。
问题之二——如果open()中的url访问的是一个绝对路径,就会报错,报错信息如下:No ‘Access-Control-Allow-Origin’ header is present on the requested resource.(浏览器的跨域行为违反了安全)
跨域
初始网站:http://store.company.com/dir/page.html
测试结果如下:
URL | 结果 | 原因 |
---|---|---|
http://store.company.com/dir2/other.html | 成功 | |
http://store.company.com/dir/inner/another.html | 成功 | |
https://store.company.com/secure.html | 失败 | 不同协议 ( https和http ) |
http://store.company.com:81/dir/etc.html | 失败 | 不同端口(80和81) |
http://news.company.com/dir/other.html | 失败 | 不同域名(news和store) |
后三种情况均为——跨域。
为什么会跨域
- 如果两个页面的协议,端口(如果有指定)和域名都相同,则两个页面具有相同的源。
- 基于浏览器的同源策略限制,限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个出于安全的策略,用于隔离潜在恶意文件的重要安全机制。
跨域在本案例的体现
源地址:file:///G:/xmapp/htdocs/ajax/ajax.html
需要访问:http://www.baidu.com
且不说端口,协议与域名均跨域了。
跨域的解决措施
推荐阅读:解决跨域的措施(比较齐全)
在开发环境等有些情况限制下,可以通过配置chrome浏览器,解决本地跨域问题。
Ajax问题之三——(采用配置chrome达解决本地跨域问题)能够读取文件,但是ajax对象实例的status=0?
ajax.onreadystatechange = function (res) {
console.log("ajax.status="+ajax.status)
if ( ajax.readyStatus == 4 && ajax.status == 200) {
console.log(ajax.responseText);
}else{
alert("error")
}
};
可以读取文件,并打印了此时ajax.status的值。
因为status=0,故没有实现预设的读取成功(status=200)的代码行。
Ajax.status
Ajax对象中有一个属性——status。
status是响应HTTP请求后,后台返回的状态值。
Ajax本该在服务器端进行数据的获取,而现在是在本地file协议上固然不支持,所以返回0。
用虚拟机模拟环境,访问localhost/ajax/ajax.html,即是以HTTP协议来访问的,故有返回的status值。
采用虚拟机模拟环境后,访问服务器的协议变成了HTTP:
关于本例中Ajax的demo所引发的思考
前端与后台的交互的方式
- HTML赋值
- JS赋值
- script填充JSON
- AJAX获取JSON
- WebSocket实时传输数据
前后端的分离,使得前后端需要数据交互
前后台分离的优点
- JavaScript可以做很大部分的数据处理工作,对服务器的压力减小。
- 后台错误不会直接反映到前台,较为友好。
- JavaScript强项在于控制整体的页面;后台的强项在于数据业务处理、维护平台的稳定性与性能等。各司其职,减少开发难度。
推荐阅读:前后端分离开发的优缺点以及如何实现前后端分离开发
文章为个人实践、整理的原创,借鉴之处均以注明,如有不足之处或错误之处,烦请指正,一起学习哟:)