天天看点

ajax跨域请求的解决办法

ajax不能跨域发送请求,因此这种情况下只能靠script标签的src属性加载所请求的数据。这种情况下js不能直接调用服务器回应的数据,只能在服务器回应的数据是function(data)的情况下,依靠回调函数获取数据。

对比src和ajax两种异步发送请求的方式,前者的好处是可以跨域,缺点是必须依靠返回值的形式是回调函数才能获取数据。后者的好处是不依赖数据的形式,但是无法跨域。

例如,我们要向地址为MyUrl的服务器发送请求,该服务器收到请求后发回一个字符串或者xml,然后我们在页面中使用这个回应的数据。

由于MyUrl是外部地址,因此用ajax的xmlhttprequest对象无法发送请求,因此只能用

<script src='MyUrl'></script>来发送请求。由于在生成这个script元素时浏览器就会自动加载src地址中的数据,因此也异步地完成了请求与应答。

对于发回的结果,必须是“方法名(参数)‘的形式,这样实际上就成了在该script元素中用取得的元素带入同名方法中执行该方法。

因此,我们还需要在生成这个script元素前,再写好同名的方法,这个方法称为“回调函数 ”(callback)。

如果发送的请求含有参数,是MyUrl?parameter=xxx&...的形式,而这个参数又需要我们动态的去根据需要生成,则我们可以不在html中写好这个<script src='MyUrl'></script>,而是用js去动态的生成这个script元素。在动态生成的script标签中会执行我们之前定义好的方法。

然后我们还需要html中定义一个js的全局变量,设为null。当我们需要提取服务器返回的结果时,我们用回调函数将获取的值赋给这个全局变量,然后再提取这个全局变量,就可以了。此处要注意的是,我们需要在动态生成的script标签加载src完毕后,再提取赋好值的全局变量。因此我们需要异步地进行。异步加载js的方法会在后面进行注释。

例如:

<script>

var result = null;//定义空的全局变量

function b(data){//这是回调函数,用进行将结果赋值给全局变量的操作

result = data;

}

function c(){//我们执行跨域发送请求并接收相应的方法

var myurl = xxx;//定义要提交请求的服务器的地址

var parameter = xxx;//定义提交的参数

var callback = "b";//定义回调函数

var script = document.createElement("script");//创建script标签

document.getElementsByTagName("head")[0].appendChild(script); //将创建的script标签添加到html文档中

script.src=myurl+"?callback="+callback+"&parameter="+parameter//根据之前我们定义/的地址和回调函数,定义整个请求地址。此处我们是假设服务器可以接受我们定义的回调///函数名,并且用”callback“参数的值来定义回调函数名。并用”回调函数名(返回值)“的方///式来向我们发送结果。如果服务器不能以”回调函数名(返回值)“这种方式发回相应,我们就彻底无法跨域了。

//下面这一段操作是异步加载js的方法,将我们在取得返回值后的操作放在取得返回值之后。 

if (script.readyState) { //IE 

script.onreadystatechange = function() {

if (script.readyState == "loaded"

|| script.readyState == "complete") {

script.onreadystatechange = null;

alert("省份:"+result[ip].province+" 城市:"+result[ip].city);//具体地操作返回值的方法,此///时是简单的弹出对话框,可以改成其他更复杂的操作。

}

};

} else { //Others: Firefox, Safari, Chrome, and Opera 

script.onload = function() {

alert("省份:"+result[ip].province+" 城市:"+result[ip].city);//具体地操作返回值的方法,此//时是简单的弹出对话框,可以改成其他更复杂的操作。

};

}

//alert("省份:"+result["222.36.223.19"].province+" 城市:"+result["222.36.223.19"].city);

}

</script>

整体的跨域请求就完成了。

对了,如果服务器不能返回 函数名(参数) 形式的字符串,也不是不能获取。但是只有通过自己的服务器进行代理请求,以解决跨域问题

如果服务器返回类似var xxx =xxx的形式,也可以调用。

继续阅读