高级课程/Ajax
用 form 可以发请求,但是会刷新页面或新开页面
用 a 可以发 get 请求,但是也会刷新页面或新开页面
用 img 可以发 get 请求,但是只能以图片的形式展示
用 link 可以发 get 请求,但是只能以 CSS、favicon 的形式展示
用 script 可以发 get 请求,但是只能以脚本的形式运行
有没有什么方式可以实现?
//get、post、put、delete 请求都行
//想以什么形式展示就以什么形式展示
因为这样的需求,AJAX出现了~~
微软的突破
IE 5 率先在 JS 中引入 ActiveX 对象(API),使得 JS 可以直接发起 HTTP 请求。
随后 Mozilla、 Safari、 Opera 也跟进(抄袭)了,取名 XMLHttpRequest,并被纳入 W3C 规范
AJAX
AJAX:异步的 JavaScript 和 XML
使用 XMLHttpRequest 发请求
服务器返回 XML 格式的字符串
JS 解析 XML,并更新局部页面
如何使用 XMLHttpRequest
myButton.addEventListener('click', (e)=>{
let request = new XMLHttpRequest()
request.open('get', '/xxx') // 配置request
request.send()
request.onreadystatechange = ()=>{
if(request.readyState === 4){
console.log('请求响应都完毕了')
console.log(request.status)
if(request.status >= 200 && request.status < 300){
console.log('说明请求成功')
console.log(typeof request.responseText)
console.log(request.responseText)
let string = request.responseText
// 把符合 JSON 语法的字符串
// 转换成 JS 对应的值
let object = window.JSON.parse(string)
// JSON.parse 是浏览器提供的
console.log(typeof object)
console.log(object)
console.log('object.note')
console.log(object.note)
}else if(request.status >= 400){
console.log('说明请求失败')
}
}
}
})
- 有趣见闻
当年ie6打遍天下无敌手,占了市场90%的市场份额,然后膨胀,微软做了一个愚蠢的决定,把之前浏览器团队,拆分了,里面的高手都被分散到别的部分,然后chorme异军突起,现在微软追悔莫及了~// - 这个功能出现一年之后不久,Gmail被开发出来了,那时候惊为天人,因为当年人都是用PC软件来收发邮件的,而Gmail是网页应用,突破通讯限制的就是AJAX技术,那时候起,人们才发现原来前端可以做很多事情,甚至说是这个技术的出现,衍生出前端这个岗位
- 对于服务器来说,返回的第四部分永远是字符串,因为这样可以解决任何需求,为什么这样说? 比如说,JavaScript语法,是一种规则,是思想的产物,具体实现是依靠浏览器这个运行环境,好比说:古代一个大臣,满腹经纶,饱读诗书有经天纬地之才,你给皇上上奏了一套治国方略,关于经济政治的优秀建议,但是皇帝不执行,你的上奏奏表就一无是处.
- 计算机语言的语法都是思想,得依靠具体的运行环境根据语法来解释你的代码,所以后台服务器和浏览器交互的时候,只要标明返回的字符有utf-8编码来解释就不会乱码,然后给定content-type 来告诉浏览器用什么语言的语法来解释这些字符串,最后返回一堆字符串让浏览器解释执行.//所以说:服务器返回的都是字符串~
- 这里有个小细节,http都是绝对路径别写'.'
同源策略
- 用过jsonp和ajax的人就会产生疑惑?/ 为什么form表单提交没有跨域问题,而ajax有跨域问题呢?
//如果你不是baidu.com 页面里的JavaScript,你就不能向baidu.com域名发起AJcX请求这就是同源策略
//什么时候才会被允许呢?//只有域名一模一样才允许,发ajax请求
只有 协议+端口+域名 一模一样才允许发 AJAX 请求
一模一样一模一样一模一样一模一样一模一样一模一样一模一样一模一样
- http://baidu.com 可以向 http://www.baidu.com 发 AJAX 请求吗 no
- http://baidu.com:80 可以向 http://baidu.com:81 发 AJAX 请求吗 no
浏览器必须保证
只有 协议+端口+域名 一模一样才允许发 AJAX 请求
CORS 可以告诉浏览器,我俩一家的,别阻止他
突破同源策略 === 跨域
为什么不允许百度公司的网站访问百度公司的网站呢?
//因为有的公司,有可能把www开头的网站卖给别人,公司不想冒险这样做
同源策略根本原因
- 因为原页面用form提交到另一个域名之后,原页面的脚本无法获取新页面的内容.也就意味着不能窃取数据,所以浏览器认为这是安全的,因为form表单会刷新啊,这个标签就是这样子的功能
- 用ajax是可以读取响应内容的,因此浏览器不能允许你这样做,也就是说,你在一个页面上用ajax发请求,是可以读取该页面所在的服务器内部数据的(现在安全人员已经做到请求,能发出去,但是拿不到响应,也就是不让你ajax拿到服务器数据)
- 本质是什么?
所以这个浏览器的同源策略,本质就是,一个域名的JavaScript代码.在未经允许的情况下,不得读取另一个域名内容,但是浏览器并不阻止你向另外一个域名发送请求.
- 本人这里有个疑惑,ajax不也是发送那些请求吗?ajax发送的请求和那些基本请求有什么区别?为什么那些普通的,比如post能发,而ajax不能?ajax那么强大,为什么不禁止它?
// 举个例子:
假设用户在访问银行网站,并且没有登出。然后他又去了任意的其他网站,刚好这个网站有恶意的js代码,在后台请求银行网站的信息(注意这里前提是你没有登出之前的银行页面,也就是说当遇到恶意JavaScript代码,他的src写的是你登录的银行网址,就等于你用登录状态打开了银行页面,页面上的信息都能发回给恶意JavaScript代码所在的页面上)。因为用户目前仍然是银行站点的登陆状态,那么恶意代码就可以在银行站点做任意事情。例如,获取你的最近交易记录,创建一个新的交易等等。因为浏览器可以发送接收银行站点的session cookies,在银行站点域上。访问恶意站点的用户希望他访问的站点没有权限访问银行站点的cookie。当然确实是这样的,js不能直接获取银行站点的session cookie,但是他仍然可以向银行站点发送接收附带银行站点session cookie的请求,本质上就像一个正常用户访问银行站点一样。关于发送的新交易,甚至银行站点的CSRF(跨站请求伪造)防护都无能无力,因为脚本可以轻易的实现正常用户一样的行为。所以如果你需要session或者需要登陆时,所有网站都面临这个问题。如果上例中的银行站点只提供公开数据,你就不能触发任意东西,这样的就不会有危险了,这些就是同源策略防护的。当然,如果两个站点是同一个组织的或者彼此互相信任,那么就没有这种危险了。