跨域访问 REST API
虽然 JQuery 也能通过授权header实现跨域, 但SharePoint 提供了更简单的方法,它被实现在SP.RequestExecutor里 。它能访问跨域的服务包括REST API, 本示例将使用它在auto-hosted的app里从远程web site去访问SharePoint。 SP.RequestExecutor 对象包含了一个独立的客户端对象的 JavaScript 库。RequestExecutor 的使用非常像 JQuery ajax() function。它用js 代码管理请求和响应。实事上 RequestExecutor能替代JQuery , 因为它也能很好的实现功能,甚至是没有跨域的情况。
针对下列情况,RequestExecutor 是非常有用的:
1. 从web browser 访问REST API .
2. 需要跨域, 像从远程的 web 页面到SharePoint app web.
3. 在SharePoint farm外访问 web service .
当使用RequestExecutor去访问外部的 web services时,远程的 web service应该要注册在 AppManifest 文件里,以便在安装app时让用户授权。本例 RequestExecutor 没有直接访问 service,它通过一个内建在SharePoint里代理页面去请求service并返回响应到页面,要让JavaScript允许跨域service的调用,否则就会被web bowser阻塞。
本例,我们将演示怎么使用它。我们将在auto-hosted 的app,然后加入一个输入框到它的default 页面,最后我们将增加一个view-model去请求REST并显示结果。
1. 打开Visual Studio 2012.
2. 创建一个新的SharePoint 2013 app.
3. 选择auto-hosted
4. 打开 Default.aspx 页面( Pages 文件夹)
5. 增加Microsoft AJAX toolkit 引用,SP.RequestExecutor将用到它:
<script type="text/javascript" src="//ajax.aspnetcdn.com/ajax/4.0/1/MicrosoftAjax.js"></script>
6. 添加 JQuery 和Knockout.
<script type="text/javascript" src="../Scripts/jquery-1.7.1.min.js"></script>
<script type="text/javascript" src="//ajax.aspnetcdn.com/ajax/knockout/knockout-2.2.1.js" ></script>
7. 替换form里的内容如下:

<form id="form1" runat="server">
<div>
<input type="text" data-bind="value: url" size="100" />
<br />
<br />
<select data-bind="value: format">
<option value="application/json;odata=verbose">application/json;odata=verbose</option>
<option value="application/atom-xml">application/atom-xml</option>
</select>
<br />
<br />
<input data-bind="click: onRunRequest" type="button" value="Execute the REST Request" />
<br />
<br />
<h1 data-bind="text: status"></h1>
<p data-bind="text: message" />
</div>
</form>

8. 保存Default.aspx.
9. 打开Default.aspx.cs .
10. 注释掉 Page_Load 里的代码.
11. 保存Default.aspx.cs .
12. 在远程 web site 项目的Script文件夹里, 创建一个文件 App.js .
13. 替换下面的view-model 代码

var appweburl = decodeURIComponent(getQueryStringParameter("SPAppWebUrl"));
var hostweburl = decodeURIComponent(getQueryStringParameter("SPHostUrl"));
$().ready(function () {
$.getScript(hostweburl + '/_layouts/15/sp.runtime.debug.js',
function () {
$.getScript(hostweburl + '/_layouts/15/sp.debug.js',
function () {
$.getScript(hostweburl + '/_layouts/15/sp.RequestExecutor.js',
function () {
ko.applyBindings(new defaultViewModel());
});
})
})
});
function defaultViewModel() {
var self = this;
self.status = ko.observable();
self.message = ko.observable();
self.url = ko.observable("/_api/SP.AppContextSite(@target)/web/lists?@target='" + hostweburl + "'");
self.format = ko.observable();
self.result = null;
self.onRunRequest = function () {
var executor = new SP.RequestExecutor(appweburl);
executor.executeAsync(
{
url: appweburl + self.url(),
method: "GET",
headers: {
"accept": self.format(),
},
success: Function.createDelegate(self, self.onComplete),
error: Function.createDelegate(self, self.onComplete)
}
);
};
self.onComplete = function (data) {
self.status(data.statusText);
self.message(data.body);
if (self.format() == 'application/atom-xml')
self.result = $(data.body)[1];
else
self.result = JSON.parse(data.body).d;
}
}
// Utility routine
function getQueryStringParameter(paramToRetrieve) {
var params =
document.URL.split("?")[1].split("&");
var strParams = "";
for (var i = 0; i < params.length; i = i + 1) {
var singleParam = params[i].split("=");
if (singleParam[0] == paramToRetrieve)
return singleParam[1];
}
}

这段代码首先从SharePoint里加载几个JavaScript 库,这些库不能放到ASP文件里,因为它们属于SharePoint,而这个页面是在SharePoint app web外面运行的,因此不能通直接在ASPX里引用。实际上,每个文件的URL是在加载时拼出来的,一旦所有需要的script被加载,view-model 对象就和以前一样被创建并被绑定到form。下一个变化是default的 REST URL:
self.url = ko.observable("/_api/SP.AppContextSite(@target)/web/lists?@target='" + hostweburl + "'");
这一行是使用SP.AppContextSite让URL去访问host web site里的list列表
onRunRequest() function 很像JQuery.Ajax,只不过它要先创建SP.RequestExecutor 对象.
var executor = new SP.RequestExecutor(appweburl);
当从我们的ap访问SharePoint REST API 时, 我们将使用app web作为目的地,这仅仅是表明请求应该送到哪,并不是最终的目的地。本例我们将使用SP.AppContextSite 对象访问host site. 如果在executeAsyn() function里提供的URL是在SharePoint外面,app web上的跨域代理将被转发请求。

self.onComplete = function (data) {
self.status(data.statusText);
self.message(data.body);
if (self.format() == 'application/atom-xml')
self.result = $(data.body)[1];
else
self.result = JSON.parse(data.body).d;
}

RequestExecutor 返回了一个 JavaScript 对象,包含status 和 body 。返回的结果是字符串,而不考虑请求的格式,这个字符串里的数据是JSON或XML格式。
14. 保存App.js file.
如果我们这时去运行这个solution,它将fail,因为它不能找到app web。一个 app web 仅仅被创建于需要时,因为我们创建了的是 auto-hosted app ,还没有在app web项目里添加任何lists或其它对象, 所以当app安装时没有app web 会被创建。因为我们需要从app web访问REST API,这不会运行正常,为了强制创建一个最小的 app web, 我们将添加一个空的element到这个项目里。
15. 右击 SharePoint app项目(不是web项目)
16. Select Add ➤ New Item….
17. 选择Empty Element item 并点击 Add, 名字不重要,随便填。
18. 按F5 运行 app.
运行的结果应该跟上一个示例差不多,不同的是这个请求是在远程web app(SharePoint farm外面)执行的,你将会看到自动加上了access token。
跨域访问 REST API的更多相关文章
- Angular2中对ASP.NET MVC跨域访问
应用场景 项目开发决定使用angular2进行前后端分离开发,由我负责后端服务的开发,起初选择的是web api进行开发.对跨域访问通过API中间件+过滤器对跨域访问进行支持.开发一段后,通知需要移植 ...
- jQuery跨域调用Web API
我曾经发表了一篇关于如何开发Web API的博客,链接地址:http://www.cnblogs.com/guwei4037/p/3603818.html.有朋友说开发是会开发了,但不知道怎么调用啊? ...
- 支持Ajax跨域访问ASP.NET Web Api 2(Cors)的简单示例教程演示
随着深入使用ASP.NET Web Api,我们可能会在项目中考虑将前端的业务分得更细.比如前端项目使用Angularjs的框架来做UI,而数据则由另一个Web Api 的网站项目来支撑.注意,这里是 ...
- ArcGIS API for Silverlight 调用WebService出现跨域访问报错的解决方法
原文:ArcGIS API for Silverlight 调用WebService出现跨域访问报错的解决方法 群里好几个朋友都提到过这样的问题,说他们在Silverlight中调用了WebServi ...
- 如何让你的 Asp.Net Web Api 接口,拥抱支持跨域访问。
由于 web api 项目通常是被做成了一个独立站点,来提供数据,在做web api 项目的时候,不免前端会遇到跨域访问接口的问题. 刚开始没做任何处理,用jsonp的方式调用 web api 接口, ...
- REST API之前端跨域访问
关键字:跨域访问,cross-origin, NodeJS, REST API, JavaScript, Access-Control-Allow-Origin 1.新建并运行一个 NodeJS的se ...
- Web Api 2(Cors)Ajax跨域访问
支持Ajax跨域访问ASP.NET Web Api 2(Cors)的简单示例教程演示 随着深入使用ASP.NET Web Api,我们可能会在项目中考虑将前端的业务分得更细.比如前端项目使用Ang ...
- Asp.Net Web Api 接口,拥抱支持跨域访问。
如何让你的 Asp.Net Web Api 接口,拥抱支持跨域访问. 由于 web api 项目通常是被做成了一个独立站点,来提供数据,在做web api 项目的时候,不免前端会遇到跨域访问接口的问题 ...
- 在dotnet core web api中支持CORS(跨域访问)
最近在写的Office add-in开发系列中,其中有一个比较共性的问题就是在add-in的客户端脚本中访问远程服务时,要特别注意跨域访问的问题. 关于CORS的一些基本知识,请参考维基百科的说明:h ...
随机推荐
- TCP在三次握手协议和四波(图)
设定TCP需要建立一个三次握手的能力,断开需要握手.整步骤,如看到下面的附图: 先来看看怎样建立连接的. 首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资 ...
- html + CSS
Html 1 html基本标签 1.1 html文件结构 <!DOCTYPE html PUBLIC "-//W3C//DTDXHTML 1.0 Transitional//EN&qu ...
- C# ICSharpCode.SharpZipLib
C# ICSharpCode.SharpZipLib.dll文件压缩和解压功能类整理,上传文件或下载文件很常用 工作中我们很多时候需要进行对文件进行压缩,比较通用的压缩的dll就是ICSharpCod ...
- elasticsearch的rest搜索---对于相关度的大牛的文档
目录: 一.针对这次装B 的解释 二.下载,安装插件elasticsearch-1.7.0 三.索引的mapping 四. 查询 五.对于相关度的大牛的文档 五.对于相关度的大牛的文档 http: ...
- 【Unity 3D】学习笔记三十八:角色控制器
角色控制器 在unity中,已经帮我们实现的上下左右跳等动作,并将他们封装成了角色控制器.角色控制器保存在unity标准资源包中,能够说是很的强大.能够模拟第一或者第三人称视角.不受刚体的限制,很适用 ...
- MAC 命令行工具(Command Line Tools)安装
不过升级后安装命令行工具(Command Line Tools)时发现官网没有clt的下载安装包了,原来改了,使用命令在线安装. 打开终端,输入命令:xcode-select --install 选择 ...
- 开始 space viking 之旅
设备 cocos2d-v2 眼下cocos2d-v3也不太稳定,它在很大程度上仍然是变化的功能. 对于稳定.我们仍然使用 v2 wget -c http://cocos2d-iphone.goo ...
- .Net 2.0实例学习:WebBrowser页面与WinForm交互技巧
原文:.Net 2.0实例学习:WebBrowser页面与WinForm交互技巧 最近看到博客园入门教学文章比较流行,自己最近又偷懒比较多,没啥心得,不妨写一篇没啥深度的入门文章吧. 话说有了WebB ...
- sqlite学习笔记5:插入数据,查询数据和删除数据
曾闻:全部的编程都是已数据为中心,觉得很有道理. 所谓数据库数据库,没有数据叫什么数据库,接下来就看看怎样在表中插入数据. 一 插入数据 1 创建一张表 首先为了插入数据,须要先创建一张表: CREA ...
- Access denied for user: 'root@localhost' (Using password: YES)
centos 设备mysql成功后 首次使用root登录发生:Access denied for user: 'root@localhost' (Using password: YES) 因为mysq ...