Ajax 请求是异步执行的, 也就是说, 要通过回调函数获得响应.
在现代浏览器上写 Ajax 主要依靠 XMLHttpRequest 对象:
- function success(text) {
- var textarea = document.getElementById('test-response-text');
- textarea.value = text;
- }
- function fail(code) {
- var textarea = document.getElementById('test-response-text');
- textarea.value = 'Error code:' + code;
- }
- var request = new XMLHttpRequest(); // 新建 XMLHttpRequest 对象
- request.onreadystatechange = function () { // 状态发生变化时, 函数被回调
- if (request.readyState === 4) { // 成功完成
- // 判断响应结果:
- if (request.status === 200) {
- // 成功, 通过 responseText 拿到响应的文本:
- return success(request.responseText);
- } else {
- // 失败, 根据响应码判断失败原因:
- return fail(request.status);
- }
- } else {
- // HTTP 请求还在继续...
- }
- }
- // 发送请求:
- request.open('GET', '/api/categories');
- request.send();
- alert('请求已发送, 请等待响应...');
当创建了 XMLHttpRequest 对象后, 要先设置 onreadystatechange 的回调函数. 在回调函数中, 通常我们只需通过 readyState === 4 判断请求是否完成, 如果已完成, 再根据 status === 200 判断是否是一个成功的响应.
XMLHttpRequest 对象的 open()方法有 3 个参数, 第一个参数指定是 GET 还是 POST, 第二个参数指定 URL 地址, 第三个参数指定是否使用异步, 默认是 true, 所以不用写.
注意, 千万不要把第三个参数指定为 false, 否则浏览器将停止响应, 直到 Ajax 请求完成. 如果这个请求耗时 10 秒, 那么 10 秒内你会发现浏览器处于 "假死" 状态.
最后调用 send()方法才真正发送请求. GET 请求不需要参数, POST 请求需要把 body 部分以字符串或者 FormData 对象传进去.
安全限制
上面代码的 URL 使用的是相对路径. 如果你把它改为'http://www.sina.com.cn/', 再运行, 肯定报错. 在 Chrome 的控制台里, 还可以看到错误信息.
这是因为浏览器的同源策略导致的. 默认情况下, JavaScript 在发送 Ajax 请求时, URL 的域名必须和当前页面完全一致.
完全一致的意思是, 域名要相同(www.example.com 和 example.com 不同), 协议要相同(http 和 https 不同), 端口号要相同(默认是: 80 端口, 它和: 8080 就不同). 有的浏览器口子松一点, 允许端口不同, 大多数浏览器都会严格遵守这个限制.
那是不是用 JavaScript 无法请求外域 (就是其他网站) 的 URL 了呢? 方法还是有的, 大概有这么几种:
一是通过 Flash 插件发送 HTTP 请求, 这种方式可以绕过浏览器的安全限制, 但必须安装 Flash, 并且跟 Flash 交互. 不过 Flash 用起来麻烦, 而且现在用得也越来越少了.
二是通过在同源域名下架设一个代理服务器来转发, JavaScript 负责把请求发送到代理服务器:
'/proxy?url=http://www.sina.com.cn'
代理服务器再把结果返回, 这样就遵守了浏览器的同源策略. 这种方式麻烦之处在于需要服务器端额外做开发.
第三种方式称为 JSONP, 它有个限制, 只能用 GET 请求, 并且要求返回 JavaScript. 这种方式跨域实际上是利用了浏览器允许跨域引用 JavaScript 资源:
JSONP 通常以函数调用的形式返回, 例如, 返回 JavaScript 内容如下:
这样一来, 我们如果在页面中先准备好 foo()函数, 然后给页面动态加一个 < script > 节点, 相当于动态读取外域的 JavaScript 资源, 最后就等着接收回调了.
来源: http://www.bubuko.com/infodetail-2862768.html