Ajax及跨域

Posted by luoway on October 20, 2015

Ajax

AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。

w3school: AJAX 简介
AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。

完整示例:

<!DOCTYPE html>
<head>
    <title>Simple XMLHttpRequest</title>
    <script type="text/javascript">
        //创建对象实例
        var xmlHttp;
        function createXMLHttpRequest() {
            if (window.ActiveXObject) {
                xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
            }
            else if (window.XMLHttpRequest) {
                xmlHttp = new XMLHttpRequest();
            }
        }

        //告诉它状态有变化怎么做,告诉它如何、向哪里发送请求
        function startRequest() {
            createXMLHttpRequest();
            xmlHttp.onreadystatechange = handleStateChange;
            xmlHttp.open("GET", "simpleResponse.xml", true);
            xmlHttp.send(null);
        }

        //什么状态做什么
        function handleStateChange() {
            if(xmlHttp.readyState == 4) {
                if(xmlHttp.status == 200) {
                    alert("The server replied with: " + xmlHttp.responseText);
                }
            }
        }
    </script>
</head>
<body>
<form action="#">
    <input type="button" value="Start Basic Asynchronous Request" onclick="startRequest();"/>
</form>
</body>
</html>

Ajax:

function ajax (url) {
	var xmlHttp;
	if(window.ActiveXObject){
		xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
	}else if(window.XMLHttpRequest){
		xmlHttp = new XMLHttpRequest();
	}

	xmlHttp.onreadystatechange = function() {
		if(xmlHttp.readyState===4){
			if(xmlHttp.status===200){
				//do something
			}
		}
	};
	xmlHttp.open("GET",url,true);
	xmlHttp.send();
}

//在js中,windows.open(‘url’)是新窗口打开网页的方法

步骤

  1. 为得到XMLHttpRequest对象实例的一个引用,可以创建一个新的实例,也可以访问包含有XMLHttpRequest实例的一个变量。
  2. 告诉XMLHttpRequest对象,哪个函数会处理XMLHttpRequest对象状态的改变,为此要把对象的onreadystatechange属性设置为指向JavaScript函数的指针。
  3. open()方法指定请求的属性。open(“GET/POST”,”url”,”布尔值”)
  4. send()方法把请求发送到url。send(String)有参数仅用于 POST 请求。

直观步骤:需要XMLHttpRequest对象的一个实例,告诉它状态有变化怎么做,告诉它如何、向哪里发送请求,最后还需要指导XMLHttpRequest发送请求。

需要注意的是,Ajax虽然是前后端交互的一种方式,但它依然是前端的内容。我们可以通过它发送请求读取、加载服务器文件,但不能修改文件。

jQuery.ajax()

w3school: jQuery 参考手册 - Ajax

最简单有效的load()load(url,data,function(response,status,xhr))

$("button").click(function(){
  $("div").load('demo_ajax_load.txt');
});

最齐全的ajax()jQuery.ajax([settings]) ,参考jQuery ajax - ajax() 方法

简写的$.get()$.post()

$.get("demo_ajax_load.txt", function(result){
  $("div").html(result);
});

$.post("ajax/test.html", function(data) {
  $(".result").html(data);
});

跨域

先来看看URL常见的结构
http:// www.mypage.com / something.jpg
方案(scheme)/ 因特网地址\服务器位置 / 资源路径

同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性。
每个源相当于一台单机的电脑,而跨域则是让这台单机的电脑能联网,访问其他电脑上、不存在于这台电脑上的文件。

segmentfault: 详解js跨域问题中讲述了5种跨域方法。

本文仅介绍通过jsonp跨域。

jsonp跨域

JSONP (JSON with Padding)
JSON:JavaScript 对象表示法(JavaScript Object Notation)

在js中,我们直接用XMLHttpRequest请求不同域上的数据时,是不可以的。但是,在页面上引入不同域上的js脚本文件却是可以的,jsonp正是利用这个特性来实现的。

<script src="http://a.com/a.js"></script>

很熟悉的跨域获取文件。
动态创建<script>标签,并读取<script>的内容,即完成了jsonp跨域。

var oScript = document.createElement('script');
oScript.src = 'http://a.com/a.js';
document.body.appendChild(oScript);

如此,我们即可访问a.js中的内容了。

如果你的页面使用jquery,那么通过它封装的方法就能很方便的来进行jsonp操作了。

<script type="text/javascript">
    $.getJSON('http://example.com/data.php?callback=?',function(jsondata){
        //处理获得的json数据
    });
</script>

jquery会自动生成一个全局函数来替换callback=?中的问号,之后获取到数据后又会自动销毁,实际上就是起一个临时代理函数的作用。$.getJSON()方法会自动判断是否跨域,不跨域的话,就调用普通的ajax方法;跨域的话,则会以异步加载js文件的形式来调用jsonp的回调函数。

另外,jquery的ajax()方法也封装了jsonp跨域方式。

$.ajax({
	type: 'GET',
	url: 'http://a.com/a.js',
	dataType: 'jsonp',
	jsonp: 'callback',
	jsonpCallback: 'myfunc',	//指定回调方法
	success: function(){
		//ajax获取成功后执行
	},
	error: function(){
		//ajax错误返回执行
	}
});

function myfunc(){
	//回调方法
}

JSONP的优缺点

JSONP的优点是:
它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更好,在更加古老的浏览器中都可以运行,不需要XMLHttpRequest或ActiveX的支持;并且在请求完毕后可以通过调用callback的方式回传结果。

JSONP的缺点则是:
它只支持GET请求而不支持POST等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。