Jsonp简单认识(后端使用的是asp.net mvc)
一、Jsonp简介:由于浏览器基于安全有同源策略(同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性)机制,所以前端无法使用Ajax来获取来获取其他域名下返回的数据,而Jsonp可以实现跨域访问。
Jsonp是基于<script>标签不受同源策略限制,可以加载任意地方的JavaScript文件来实现的。Jsonp实现理念就是,和服务端约定好一个函数名,当请求文件时,服务端返回一段JavaScript。这段JavaScript调用了约定好的函数,并且将数据当做参数传入。
二、简单Demo
1、在visual studio新建项目JsonpDemo和项目OtherDomain,项目结构如下
2、在JsonpDemo项目中新增HomeController及其视图,视图中代码如下:
@{
Layout = null;
} <!DOCTYPE html> <html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<div>
<input type="button" id="getJsonpByHand" value="get jsonp by hand" />
</div>
<script type="text/javascript" >
$("#getJsonpByHand").click(function () {
//55157位OtherDomain项目启动后网站的端口
CreateScript("http://localhost:55157/home/somejsonp?");
})
function CreateScript(src) {
$("<script><//script>").attr("src", src).appendTo("body")
}
//myCallBack就是与后端约定好的函数
function myCallBack(data) {
console.log(data);
}
</script>
</body>
</html>
3、在OtherDomain项目中新增HomeController及其视图,HomeController中代码如下:
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc; namespace OtherDomain.Controllers
{
public class HomeController : Controller
{
//
// GET: /Home/ public ActionResult Index()
{
return View();
} public ActionResult SomeJsonp()
{
return new ContentResult()
{
//myCallBack为服务端与前端约定好的函数
Content = "myCallBack(" + JsonConvert.SerializeObject(new { Name = "Tom", Age = }) + ")",
ContentType = "text/html"
};
} }
}
4、启动两个项目,点击JsonpDemo项目页面中的按钮,谷歌浏览器控制台下看到
三、对上面Demo做一下简单优化,可以通过前端来指定与服务器约定的函数
1、修改JsonpDemo项目index.cshtml页面中,按钮点击事件下CreateScript方法传入参数为:http://localhost:55157/home/somejsonp?callback=myCallBack 也就是加上一个URL参数
2、修改OtherDomain项目下HomeController.cs中SomeJsonp方法如下:
public ActionResult SomeJsonp()
{
string func = Request.Params["callback"];
return new ContentResult()
{
Content = func+"(" + JsonConvert.SerializeObject(new { Name = "Tom", Age = }) + ")",
ContentType = "text/html"
};
}
四、通过jQuery使用Jsonp实现跨域请求
1、继续沿用上面两个项目,修改JsonpDemo项目index.cshtml页面代码,新增一个按钮,并实现其click事件相关代码,如下:
@{
Layout = null;
} <!DOCTYPE html> <html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<script src="~/Scripts/jquery-1.8.2.min.js"></script>
</head>
<body>
<div>
<input type="button" id="getJsonpByHand" value="get jsonp by hand" />
<input type="button" id="getJsonpByJquery" value="get jsonp by jquery" />
</div>
<script type="text/javascript" >
$("#getJsonpByHand").click(function () {
CreateScript("http://localhost:55157/home/somejsonp?callback=myCallBack");
})
function CreateScript(src) {
$("<script><//script>").attr("src", src).appendTo("body")
}
$("#getJsonpByJquery").click(function () {
$.ajax({
// url: 'http://localhost:55157/home/somejsonp?callback=myCallBack',
url: 'http://localhost:55157/home/somejsonp',
dataType: "jsonp",
jsonp: "callback",
success: function (data) {
console.log(data)
var a=123;
var b=2;
var c=35;
}
})
})
//function myCallBack(data) {
// console.log(data);
//}
</script>
</body>
</html>
注意上面ajax参数dataType为jsonp,jsonp为callback
2、OtherDomain下HomeController.cs文件SomeJsonp代码和第三个里面代码一样,如下:
public ActionResult SomeJsonp()
{
string func = Request.Params["callback"];
return new ContentResult()
{
Content = func + "(" + JsonConvert.SerializeObject(new { Name = "Tom", Age = }) + ")",
ContentType = "text/html"
};
}
3、运行两个项目,点击“get jsonp by jquery”按钮,可以在谷歌浏览器控制台下看到同样结果
4、注意:如果前端代码传入callback参数,那么前端也要自己实现相应参数的函数。如果没有传入,其实jQuery自己会默认传入并自己实现。
五、扩展:在OtherDomain项目下,简单自定义JsonpResult类,代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc; namespace OtherDomain
{
public class JsonpResult : JsonResult
{
private const string CALLBACK_QUERYSTRING = "callback";
//private const string CALLBACK_CONTENTTYPE = "application/x-javascript";
private const string CALLBACK_CONTENTTYPE = "text/javascript"; public override void ExecuteResult(ControllerContext controllerContext)
{
if (controllerContext != null)
{
var request = controllerContext.HttpContext.Request;
object callback = request[CALLBACK_QUERYSTRING];
if (callback == null)
{
controllerContext.RouteData.Values.TryGetValue(CALLBACK_QUERYSTRING, out callback);
} var hasCallback = !string.IsNullOrWhiteSpace(callback == null ? "" : callback as string);
if (hasCallback)
{
SetContentTypeIfEmpty();
var response = controllerContext.HttpContext.Response;
response.Write(callback);
response.Write("(");
base.ExecuteResult(controllerContext);
response.Write(")");
}
else
{
base.ExecuteResult(controllerContext);
}
}
} private void SetContentTypeIfEmpty()
{
if (string.IsNullOrWhiteSpace(base.ContentType))
{
base.ContentType = CALLBACK_CONTENTTYPE;
}
}
} public static class ContollerExtensions
{
public static JsonpResult Jsonp(this Controller controller, object data, JsonRequestBehavior behavior = JsonRequestBehavior.DenyGet)
{
JsonpResult result = new JsonpResult();
result.Data = data;
result.JsonRequestBehavior = behavior;
return result;
}
}
}
JsonpResult及ContollerExtensions
如果想要很好的结合到controller中,需要写如上ContollerExtensions的Controller的扩展方法
在OtherDomain项目下,需要修改SomeJsonp方法:
public ActionResult SomeJsonp()
{
return this.Jsonp(new
{
Name= "Tom",
Age=
}, JsonRequestBehavior.AllowGet);
}
Jsonp简单认识(后端使用的是asp.net mvc)的更多相关文章
- Asp.net Mvc模块化开发之“开启模块开发、调试的简单愉快之旅”
整个世界林林种种,把所有的事情都划分为对立的两个面. 每个人都渴望的财富划分为富有和贫穷,身高被划分为高和矮,身材被划分为胖和瘦,等等. 我们总是感叹,有钱人的生活我不懂;有钱人又何尝能懂我们每天起早 ...
- Asp.net Mvc模块化开发之“部分版本部分模块更新(上线)”
项目开发从来就不是一个简单的问题.更难的问题是维护其他人开发的项目,并且要修改bug.如果原系统有重大问题还需要重构. 怎么重构系统不是本文探讨的问题,但是重构后如何上线部署和本文关系密切.这个大家可 ...
- ASP.NET MVC防范CSRF最佳实践
XSS与CSRF 哈哈,有点标题党,但我保证这篇文章跟别的不太一样. 我认为,网站安全的基础有三块: 防范中间人攻击 防范XSS 防范CSRF 注意,我讲的是基础,如果更高级点的话可以考虑防范机器人刷 ...
- Asp.net Mvc模块化开发之分区扩展框架
对于一个企业级项目开发,模块化是非常重要的. 默认Mvc框架的AreaRegistration对模块化开发真的支持很好吗?真的有很多复杂系统在使用默认的分区开发的吗?我相信大部分asp.net的技术团 ...
- Asp.net Mvc模块化开发系列(目录)
模块化开发是非常重要的,模块化开发是个系统性问题,为此我觉得有必须要写一个系列的文章才能基本说的清楚 那又为什么要写一个目录呢? 其一.是对我昨天承诺写一个系列新的文章的回应 其二.是先写出一个大纲, ...
- 7 天玩转 ASP.NET MVC — 第 1 天
0. 前言正如标题「7 天玩儿转 ASP.NET MVC」所言,这是个系列文章,所以将会向大家陆续推出 7 篇.设想一下,一天一篇,你将从一个愉快的周一开始阅读,然后在周末成为一个 ASP.NET M ...
- ASP.NET MVC学习之模型绑定(1)
一.前言 下面我们将开始学习模型绑定,通过下面的知识我们将能够理解ASP.NET MVC模型的模型绑定器是如何将http请求中的数据转换成模型的,其中我们重点讲述的是表单数据. 二.正文 1.简单类型 ...
- 7 天玩转 ASP.NET MVC - 第 1 天
0. 前言 正如标题「7 天玩儿转 ASP.NET MVC」所言,这是个系列文章,所以将会向大家陆续推出 7 篇.设想一下,一天一篇,你将从一个愉快的周一开始阅读,然后在周末成为一个 ASP.NET ...
- AngularJS html5Mode与ASP.NET MVC路由共存
前言 很久之前便听说AngularJS,非常酷,最近也比较火,我也在持续关注这个技术,只是没有认真投入学习.前不久公司找我们部门做一个OA系统(想省下几万大洋的费用),第一时间便想到AngularJS ...
随机推荐
- C++ map的使用
C++ map的基本操作和使用 来源:(http://blog.sina.com.cn/s/blog_61533c9b0100fa7w.html) - C++ map的基本操作和使用_Live_新浪博 ...
- Linux 网络编程三(socket代码详解)
//网络编程客户端 #include <stdio.h> #include <stdlib.h> #include <string.h> #include < ...
- python中class 的一行式构造器
好处:避免类初始化时大量重复的赋值语句 用到了魔法__dict__ # 一行式构造器 class Test(): # 初始化 def __init__(self, a, b, c=2, d=3, e= ...
- JS 之继承
ECMAScript继承是通过原型链来继承的.基本思想是利用原型来让一个引用类型继承另一个引用类型的属性和方法,使原型变为另一个对象的实例.通过原型链实现继承时,不能使用对象字面量创建原型方法,避免重 ...
- 前端开发工程师:网易web前端课程,价值1499元【无水印版】
这套网上的朋友购买分享给我的,特此分享~ 让大家都受益 早日成为强大的web前端开发工程师!!赶紧回复下载吧 下载地址:http://fu83.cn/thread-172-1-1.html
- 在opencv3中的机器学习算法
在opencv3.0中,提供了一个ml.cpp的文件,这里面全是机器学习的算法,共提供了这么几种: 1.正态贝叶斯:normal Bayessian classifier 我已在另外一篇博文中介 ...
- Gradle tip #1: tasks
With this post I would like to start series of Gradle-related topics I wish I knew when I first star ...
- CUDA编程学习(二)
将数据加载到GPU后,如何在grid下的block进行并行计算(一个grid包含多个block) /****How do we run code in parallel on the device** ...
- Win10/UWP开发—使用Cortana语音指令启动前台App
这两天进群(53078485)找大咖的童鞋比较多,只是大咖比较忙,目前Demo还没有要到,这里先给大家转载一篇Aran大咖的博客学习下,以下是原文: Win10开发中最具有系统特色的功能点绝对少不了集 ...
- JavaScript实例-----反选
<!DOCTYPE HTML> <html> <head> <script> function myFunction() { var oTab = do ...