愿你坚持不懈,努力进步,进阶成自己理想的人

—— 2017.09, 写给3年后的自己

Javascript学习总结——AJAX与同源策略

AJAX是Asynchronous Javascript And XML的缩写,允许Javascript执行异步网络请求

1、现代浏览器上使用XMLHttpRequest创建请求对象,对于老的IE浏览器,则用ActiveXObject('Microsoft.XMLHttp'),如:

var request;
if(window.XMLHttpRequest) {
  request = new XMLHttpRequest();
} else {
  request = new ActiveXObject("Microsoft.XMLHTTP");
}

2、建立AJAX请求,使用request.open(),这个方法有三个参数,第一个参数指定请求方式(POST/GET),第二个参数指定请求的URL,第三个参数指定是否异步请求(默认async为true),如:

request.open("GET", "/data.json");

3、请求建立后,还需要使用request.send()进行发送,这个方法只有一个可选的参数,指定发送给server的string,如:

request.send();

或者对于一个POST请求:

request.open("POST", "form.php", true);
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
request.send("name=RuphiLau&age=21");

4、监听和处理请求,示例如下:

request.onreadystatechange = function() {
  /* readyState属性用于判断请求的状态
    0: 请求未初始化
    1: 服务器连接已建立
    2: 请求已接收
    3: 请求处理中
    4: 请求已完成,且响应已就绪
  */
  /* status记录HTTP相应状态,有200(成功),404(未找到)*/
  if(request.readyState == 4 && request.status == 200) {
    // 成功后,可以用request.responseText获取相应的文本
    console.log(request.responseText);
  } else {
    console.log("error");
  }
}

5、浏览器的同源策略

  • 在浏览器的同源策略下,AJAX只能对同源的URL发送请求
  • 同源是指:有同样的域名(https://www.a.comhttps://a.com不同),协议相同(比如httphttps不同),端口相同(有的浏览器可能会允许相同)

6、同源策略下请求外域的解决方案?

  1. 使用中间代理服务器转发请求URL,达到满足同源的目的,如/proxy?url=https://www.a.com
  2. 使用window.name或者window.domain配合iframe
  3. 使用window.postMessage()
  4. 使用JSONP技术,如:https://www.a.com/response中的内容:
Speak("Hello, world!");

https://www.b.com/index.html的内容:

<!DOCTYPE html>
<html>
<head>
  <title>Test</title>
</head>
<body>
<script type="text/javascript">
function Speak(string) {
  alert(string);
}
</script>
<script type="text/javascript" id="jsonp"></script>
<script type="text/javascript">
function sendJSONPRequest() {
  document.getElementById('jsonp').src = "https://www.a.com/response";
}

sendJSONPRequest();
</script>
</body>
</html>

执行后,将弹出“Hello World”

  1. HTML5中的CORS(Cross-Origin Resource Sharing),Orgin表示本域,当JS向外域发起请求的时候,要经过一个握手验证的过程,也就是:

[a.com] -----------------------------> [b.com]GET /data.json
Host: b.com
User-Agent: Mozilla/5.0 xxx
Origin: https://a.com
[a.com] <----------------------------- [b.com]
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://a.com

这样子一来,就相当于a.com是经过b.com认证的,所以就可以获得数据了

注意,CORS只允许简单请求(包括GET/HEAD/POST,且POST的Content-Type只可以是
application/x-www-form-urlencodedmultipart/form-datatext/plain
,不能包含自定义的头)