同源策略 不了解的可以先了解一下先
第一种:修改asp.net mvc 配置文件 Web.fonfig
在 Web.config 中的 节点添加 如下代码:
<!--允许跨域访问-->
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="*" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE" />
</customHeaders>
</httpProtocol>
<!--允许跨域访问-->
页面效果:
第二种:JSONP
第一步 : 随便创建一个html页面 ,引入jquery
代码如下 : 要注意 dataType 不要写成 datatype 这里大小写敏感,
jsonpCallback 也大小写敏感不要写错, 内容随便写就行 例如这里的doSuccess ,不要太作死就行
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>demo</title>
</head>
<body>
<script src="jquery.js"></script>
<script>
$(function (){
var content = {
url : 'http://localhost:59536/Home/About',
type : 'get',
dataType :'jsonp',
jsonpCallback : "doSuccess",
success : function(e){
alert('成功');
},
error :function(a,b,c){
alert(a.status);
alert(b);
alert(c);
alert('失败');
}
}
$.ajax(content);
})
</script>
</body>
</html>
第二步:创建一个asp.net MVC项目
创建成功后:
修改 Home控制器中的About方法
修改完成后的Home控制器:
注意:方法中 Request.QuerryString["callback"] 就是 html页面上的 jsonpCallback 的值
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Newtonsoft.Json;
namespace Test.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult About()
{
//获取回调函数
var callBack = Request.QueryString["callback"]; //这里得到的 就是 前端的 jsoonpCallback的 值
//创建假数据
var data = new
{
success = true,
msg = "成功"
};
//将对象序列化为json字符串
var jsonStr = JsonConvert.SerializeObject(data);
//拼接为jsonp格式 即 回调函数名(json数据格式)
var res = callBack + "(" + jsonStr + ")";
//返回jsonp
return Content(res);
}
public ActionResult Contact()
{
ViewBag.Message = "Your contact page.";
return View();
}
}
}
右键Test项目 -- 点击属性 --点击web 可以看见给的端口号 前端页面的url 就写 http://localhost:59536/Home/About
然后点击运行,再打开写好的前端页面
展示:
最后我们再一起来捋细节:
看一下 在vs 2017 设置断点 得到的 callBack
疑点一:
果然是 我们随意设置的 doSuccess 吧
既然 jsonpCallbcak 是为了设置回调函数的属性, 就可以在ajax 外创建一个叫 doSuccess的 js函数 来执行,
只是我们这里没有这个需求用success() 就已经满足了,如果创建了函数doSuccess ,那么doSuccess和 success都会被执行.
疑点二:
什么是Jsonp格式 ?
在遇到跨域问题前,真的不知道.
json 格式我们是知道的 ,jsonp 就大致可以理解为 回调函数名( json数据 )
可以看见我在 Home控制器 中写的 返回的参数的格式,就是把 json 放到 回调函数名( )中
疑点三:
jsonpCallback 可以不写吗?
答案是: 可以不写 ,在我们不需要回调函数做一些其他的事的时候,就像这个例子 success() 方法就已经满足了
在不写的情况下 jQuery 会为我们默认添加一个 jsonpCallback 如果不信我们注释jsonpCallback后再去vs2017 断点看一下
示例:
没有骗你吧?
疑点四:
success方法收到的数据到底长什么样?
我们再浏览器上f12 找到 success 设置断点 查看一下:
可以看见用于包裹数据的 回调函数消失了 success 收到了 json格式的数据 ,又可以愉快的玩耍了
疑点五:
在服务器端也就是 控制器中的About方法 可以不以 jsonp的格式返回数据,直接返回 json吗 ?
那么我们修改代码试试:
把res改为了 jsonStr 再开始调试
页面显示: 明显走了 error函数
对 error函数 的三个参数不了解的同学可以看看这位博主的文章非常详细 : jquery ajax error函数和及其参数详细说明
蛋疼: http状态码是200, 也就是成功,成功还走error太任性了
解析错误: parsererror 代表解析错误
翻译: jQuery啥啥啥省略部分字 没有被调用 ,聪明的话就知道是jQuery默认添加的回调函数没有被调用
到这里我们知道了 服务器返回的 回调函数名( json数据) 就相当于返回了一段要被执行的js 而且只有只有这个回调函数被执行了才不报错.
再来看看控制台的报错信息:
报错类型是最简单的语法错误,不要傻乎乎的检查代码了
我们点击上面的箭头所指看看:
看到了吗,数据就在这,不以jsonp格式写你就是拿不到它
把 返回类型修改回来 ,又一切正常了