前端:(4) jQuery笔记----AJAX - 跨域
一、jsonp
其实我本以为jsonp能够做到利用AJAX任意访问别人的程序代码,但是我发现实际并不是我想象的那样,因为jsonp要改动服务器端的代码。别人的服务器端代码怎么改啊?除非别人愿意,否则你还是不能用AJAX获取别人的数据。
Ajax直接请求普通文件存在跨域无权限访问的问题,甭管你是静态页面、动态网页、web服务、WCF,只要是跨域请求,一律不准;其实jsonp的原理就是远程执行js。
<script type="text/javascript" src="远程js文件"></script>
示例-服务器端代码:
namespace AJAXDomain.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult GetPerson()
{
Person p = new Person();
p.Id = 1;
p.Name = "刘备";
p.Age = 24;
JavaScriptSerializer jss = new JavaScriptSerializer();
string json = jss.Serialize(p); //序列化成JSON
string callback = Request["callback"]; //拼接有点奇葩
string call = callback + "(" + json + ")"; //callback拼接上括号和继承的json
return Content(call);
}
}
public class Person
{
public int Id
{
get;
set;
}
public string Name
{
get;
set;
}
public int Age
{
get;
set;
}
}
}
修改hosts表:
127.0.0.1 www.baidu.com
前台页面代码:
<html>
<head>
<title>Index</title>
<script src="jquery-1.7.1.min.js"></script>
<script type="text/javascript">
$(function () {
//下面这段是直接获取本域名下的json,但是不支持跨域
//$.ajax({
// url: "http://www.baidu.com:8881/Home/GetPerson",
// type: "get",
// dataType: "text",
// success: function (response) {
// var p = getObject(response);
// $("#div1").text("姓名:" + p.Name + "年龄:" + p.Age);
// }
//})
//跨域AJAX(jsonp)
$.ajax({
type: "get",
async: false,
url: "http://www.baidu.com:8881/Home/GetPerson",
dataType: "jsonp",
jsonp: "callback", //传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)
//jsonpCallback:"?", //自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据
success: function(p){
//var p = getObject(json); //这里要注意下,jsonp返回之后jQuery会直接转成js对象,不用再转了。
$("#div1").text("姓名:" + p.Name + "年龄:" + p.Age);
alert(p.Name);
},
error: function(){
alert('跨域失败!');
}
})
})
function getObject(str) {
return eval("(" + str + ")");
}
</script>
</head>
<body>
<div>
测试跨域:
</div>
<div id="div1">
</div>
</body>
</html>
页面输出的效果如下:
二、代理访问
代理访问实际上就是通过后端代码如.NET、JAVA、PHP获取到数据,再返回。这个没什么好说的,你搞个WebClient下载页面字符串,再发给前台而已。
三、iframe方法
这个适合同一主域名的二级域及主域名之间的相互访问。比如:www.a.com和blog.a.com之间的ajax交互,在两个域下的页面都加上document.domain = "a.com"就可以了。
其次,是不同主域名之间的iframe跨域:
namespace MVC___学习测试.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
//模拟跨域页,假设这个是不同域名的页
public ActionResult GetData()
{
return View();
}
public ActionResult GetPerson()
{
Person p = new Person();
p.Id = 1;
p.Name = "刘备";
p.Age = 24;
return Json(p, JsonRequestBehavior.AllowGet);
}
}
public class Person
{
public int Id
{
get;
set;
}
public string Name
{
get;
set;
}
public int Age
{
get;
set;
}
}
}
GetData视图:
<html>
<head>
<title>同域页</title>
<script type="text/javascript" src="/Scripts/jquery-1.4.1.min.js"></script>
<script type="text/javascript">
function getObject(str) {
return eval("(" + str + ")");
}
$(function() {
//下面这段是直接获取本域名下的json
$.ajax({
url: "http://localhost:5908/Home/GetPerson",
type: "get",
dataType: "text",
success: function(response) {
var p = getObject(response);
parent.SonRun(p); //通过parent获取父窗口的变量、函数等,将返回值传过去,实际上不过是对windows.parent对象的理解。
}
})
})
</script>
</head>
<body></body>
</html>
Index视图:
<html>
<head>
<title>IFrame跨域测试</title>
<script type="text/javascript" src="/Scripts/jquery-1.4.1.min.js"></script>
<script type="text/javascript">
function SonRun(p)
{
$("#div1").text(p.Id + p.Name + p.Age);
}
</script>
</head>
<body>
<iframe id="if1" width="0" height="0" src="http://localhost:5908/Home/GetData"></iframe>
<div id="div1"></div>
</body>
</html>
输出如下: