ajax跨域问题我只学一种解决方案

Ajax跨域问题的jsonp解决方案javascript

在前端咱们常常会使用Ajax来向服务器发送请求和接收服务器响应回来的数据,通常来讲在同一个服务器的数据来往是没有什么问题的,可是有时使用Ajax请求数据并不局限于同一个服务器,跨服务器请求就会遇到跨域问题,下面咱们探讨一下跨域问题是怎么产生的,最优的解决方案是什么?php

同源策略

同源策略是浏览器的一种安全策略,是为了保护本地数据不被从其余服务器获取回来的数据污染,从而拒绝接受非本服务器响应回来的数据.这样的后果就是咱们能成功的向其余的服务器发送数据请求,对方也能成功响应并返回数据,html

可是,就是没有办法接受数据,由于浏览器拦截了.前端

这里解释一下"同源"的概念:java

协议,域名,端口都一致视为同源,有其中一个不一样则为不一样源jquery

跨域问题

上面已经解释了什么是同源,能够理解为同源即同域,若是在非同源的基础上,想要进行数据来往,这时就会出现咱们所说的跨域问题web

怎么解决Ajax的跨域问题

一共有六种方案:ajax

  • jsonp
  • document.domain+iframe
  • document.hash+iframe
  • window.name+iframe
  • window.postMessage
  • flash等第三方插件

注意:我下面要讲的解决方案是jsonp,在讲jsonp以前我先讲基础的同源的jQuery的Ajax的写法json

同源的jQuery的Ajax的实现

1.环境

phpstudyapi

2.目录结构

3.index.html文件
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<script src="http://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>
	</head>
	<body>
		<button class="btn">获取数据</button>
		<script type="text/javascript"> $(function() { $(".btn").click(function() { $.ajax({ type: "get", url: "./data.php", dataType:"json", success: function(data) { //var data=JSON.parse(data); console.log(data.username);//zhangsan console.log(data.age);//12 }, error: function() { console.log("获取失败"); } }); }) }) </script>
	</body>
</html>

复制代码
4.data.php文件
<?php
	$arr=["username"=>"zhangsan","age"=>12];
	echo json_encode($arr);
?>
复制代码

运行结果

注意:

  • 上面的代码在同源的状况下可以成功请求到data.php,并成功打印出数据

  • //jQuery中通常不须要json数组转化为对象,只须要指定数据的类型是json类型便可
    dataType:"json"//默认为文本型
    复制代码

跨域的jQuery的Ajax

为了实现Ajax的跨域请求,须要将上面例子的基础上,将index.html文件中Ajax请求的路径改成不一样域名的网站,我在phpstudy环境中映射了一个目录并指定一个域名,下面的例子咱们就来跨域访问该目录下的data.php文件

修改index.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<script src="http://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>
	</head>
	<body>
		<button class="btn">获取数据</button>
		<script type="text/javascript"> $(function() { $(".btn").click(function() { $.ajax({ type: "get", url: "http://www.web2.com/data.php", dataType:"json", success: function(data) { //var data=JSON.parse(data); console.log(data.username);//zhangsan console.log(data.age);//12 }, error: function() { console.log("获取失败"); } }); }) }) </script>
	</body>
</html>
复制代码

data.php文件

<?php
	$arr=["username"=>"zhangsan","age"=>12];
	echo json_encode($arr);
?>
复制代码

运行结果

从上面的结果来看,跨域请求数据成功,对方响应也成功了,可是被浏览器拦截了,这就是典型的跨域问题

下面咱们来解决这个问题,并能在前台成功读取返回来的值

JSONP的实现

jsonp这种解决跨域问题方案一共有两种方法

  • 静态script标签的src属性进行跨域请求
  • 动态建立script标签,经过标签的src属性进行跨域请求
静态script标签的src属性进行跨域请求

在前端的页面中将跨域的请求的URL赋值给script标签的src属性

<script src="http://www.web2.com/data.php"></script>
复制代码
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<script src="http://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>
	</head>
	<body>
		<button class="btn">获取数据</button>
		<script src="http://www.web2.com/data.php"></script>
		<script type="text/javascript"> $(function() { $(".btn").click(function() { console.log(temp); }) }) </script>
	</body>
</html>

复制代码

data.php

<?php
	//echo "var temp=111";//传单个值
	$arr=["username"=>"zhangsan","age"=>12];//项目中经常传数组
	$arr=json_encode($arr);
	echo "var temp=".$arr;
?>
复制代码

不难发现这种传值的方式有些麻烦,下面介绍动态建立script标签,经过标签的src属性进行跨域请求

动态建立script标签,经过标签的src属性进行跨域请求

原生js写法

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<script src="http://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>
	</head>
	<body>
		<script type="text/javascript"> //动态建立 var script=document.createElement("script"); script.src="http://www.web2.com/data.php?callback=gdata"; var head=document.getElementsByTagName('head')[0]; head.appendChild(script); function gdata(data){ console.log(data.username); console.log(data.age); } </script>
	</body>
</html>
复制代码

data.php

<?php
	$arr=["username"=>"zhangsan","age"=>12];
	$arr=json_encode($arr);
	$cb=$_GET['callback'];
	echo $cb.'('.$arr.')';//调用回调函数,注意拼接的方式,
?>
复制代码

注意: 在上面的这种方法中,回调函数名字默认是callback,JQuery官方文档有说明,固然也能够是其余名字,这个名字由后台人员定义,再告诉前端人员,不然前端人员将没法使用正确的回调函数名获取值 咱们知道,在实际的项目中,咱们常常使用的是jQuery的写法

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<script src="http://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>
	</head>
	<body>
		<button class="btn">获取数据</button>
		<script type="text/javascript"> $(function() { $(".btn").click(function() { $.ajax({ type: "get", url: "http://www.web2.com/data.php", dataType:"jsonp",//注意类型为jsonp success: function(data) { console.log(data.username);//zhangsan console.log(data.age);//12 }, error: function() { console.log("获取失败"); } }); }) }) </script>
	</body>
</html>
复制代码

到此为止,咱们就讲完了Ajax跨域请求的jsonp解决方案,可是在实际的调用别人的api时还会有其余要注意的问题,好比须要在发送请求时同时将使用api的密钥发送过去

相关文章
相关标签/搜索