虽然 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。

SharePoint 2013 APP 开发示例 系列

 
 
分类: Sharepoint

跨域访问 REST API的更多相关文章

  1. Angular2中对ASP.NET MVC跨域访问

    应用场景 项目开发决定使用angular2进行前后端分离开发,由我负责后端服务的开发,起初选择的是web api进行开发.对跨域访问通过API中间件+过滤器对跨域访问进行支持.开发一段后,通知需要移植 ...

  2. jQuery跨域调用Web API

    我曾经发表了一篇关于如何开发Web API的博客,链接地址:http://www.cnblogs.com/guwei4037/p/3603818.html.有朋友说开发是会开发了,但不知道怎么调用啊? ...

  3. 支持Ajax跨域访问ASP.NET Web Api 2(Cors)的简单示例教程演示

    随着深入使用ASP.NET Web Api,我们可能会在项目中考虑将前端的业务分得更细.比如前端项目使用Angularjs的框架来做UI,而数据则由另一个Web Api 的网站项目来支撑.注意,这里是 ...

  4. ArcGIS API for Silverlight 调用WebService出现跨域访问报错的解决方法

    原文:ArcGIS API for Silverlight 调用WebService出现跨域访问报错的解决方法 群里好几个朋友都提到过这样的问题,说他们在Silverlight中调用了WebServi ...

  5. 如何让你的 Asp.Net Web Api 接口,拥抱支持跨域访问。

    由于 web api 项目通常是被做成了一个独立站点,来提供数据,在做web api 项目的时候,不免前端会遇到跨域访问接口的问题. 刚开始没做任何处理,用jsonp的方式调用 web api 接口, ...

  6. REST API之前端跨域访问

    关键字:跨域访问,cross-origin, NodeJS, REST API, JavaScript, Access-Control-Allow-Origin 1.新建并运行一个 NodeJS的se ...

  7. Web Api 2(Cors)Ajax跨域访问

    支持Ajax跨域访问ASP.NET Web Api 2(Cors)的简单示例教程演示   随着深入使用ASP.NET Web Api,我们可能会在项目中考虑将前端的业务分得更细.比如前端项目使用Ang ...

  8. Asp.Net Web Api 接口,拥抱支持跨域访问。

    如何让你的 Asp.Net Web Api 接口,拥抱支持跨域访问. 由于 web api 项目通常是被做成了一个独立站点,来提供数据,在做web api 项目的时候,不免前端会遇到跨域访问接口的问题 ...

  9. 在dotnet core web api中支持CORS(跨域访问)

    最近在写的Office add-in开发系列中,其中有一个比较共性的问题就是在add-in的客户端脚本中访问远程服务时,要特别注意跨域访问的问题. 关于CORS的一些基本知识,请参考维基百科的说明:h ...

随机推荐

  1. FFmpeg 协议初步学习

    typedef struct URLContext { const AVClass *av_class; /**< information for av_log(). Set by url_op ...

  2. duplicate symbol _*** in:

    duplicate symbol _kReachabilityChangedNotification in: 问题出在同一个文件被引用两次,在项目中找到引用的地方,删掉对应的引用

  3. 2440裸 Delay(); 和 while(!(rUTRSTAT0 &amp; 0x2)); 问题

    前两天写RTC中断 使用串行输出 它发现,该方案将while(!(rUTRSTAT0 & 0x2));走不出的情况.的 解决方法: main函数添加: U32 mpll_val = 0,con ...

  4. sql事务,在sql2000里判断执行是否成功用@@ERROR 判断

    原文:sql事务,在sql2000里判断执行是否成功用@@ERROR 判断 贴个sql事务,在sql2000里判断执行是否成功用@@ERROR 判断 这个东西多少还是有点问题,sql2005了可以用t ...

  5. 安全系列之二:OAuth2.0 开放授权协议

    本文提取出OAuth2.0规范RFC6749的主要内容,部分内容从文档复制出来,给大家讲讲第三方授权背后的故事. 先是举个知乎的QQ登录授权的例子,然后讲四种授权方式,两种令牌,接着是看看协议流程,分 ...

  6. C++外观设计模式模式(三)

    3.外观模式总结 引入了外观类.解除了客户类与子系统的耦合性.客户类不须要直接操作子系统,而是由外观类负责处理,对client而言是透明的,客户类仅仅须要操作外观类就能够了,符合"迪迷特法则 ...

  7. [C#]设置或取消开机启动(注册表形式)

    原文:[C#]设置或取消开机启动(注册表形式) 使用代码: 代码效果:

  8. SURF分析算法

    SURF分析算法 一个.整体形象     这个概念是积分图像Viola和Jones建议.随机位积分图像(i.j)的值原始图象的左上角随机点(i,j)级配相应的重点领域值的总和,其数学公式如图1所看到的 ...

  9. SQL常规查询详解

    一.交叉连接(cross join) 交叉连接(cross join):有两种,显式的和隐式的,不带on子句,返回的是两表的乘积,也叫笛卡尔积. 例如:下面的语句1和语句2的结果是相同的. 语句1:隐 ...

  10. 个人学习JQ插件编写成果:little酷炫的图片滑动切换效果

    工作一个多月了,好久没来冒冒泡了,看了@wayong的JQ插件教程,自己编写了一个模仿拉勾网首页广告栏滑动特效的JQ插件,现在跟朋友们分享分享! 先上demo链接:http://runjs.cn/de ...