虽然 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. Unity3D脚本--真实1

    1. Unity3D动作脚本 Unity3D脚本用于Unity3D发动机订单公布. JavaScript全局变量:在Inspector中能够看到,且能够改动其值.其他脚本可调用此变量. C#公有(pu ...

  2. async和await关键字实现异步编程

    async和await关键字实现异步编程 异步编程   概念 异步编程核心为异步操作,该操作一旦启动将在一段时间内完成.所谓异步,关键是实现了两点:(1)正在执行的此操作,不会阻塞原来的线程(2)一旦 ...

  3. [Android] Upload package to device fails #2720

    错误描述: 解决办法:   来源:https://facebook.github.io/react-native/docs/android-setup.html

  4. 关于启动调试时,总是启动多个web端口的问题

    在一个解决方案中,经常包含多个web项目,当设置某一个web项目为起始项目后,启动调试,会发现其他的web项目的端口也会一起打开,显示在电脑的右下方,其实开启其他端口有时是没必要的,只是多占用了系统内 ...

  5. MVC4的过滤器

    过滤器 提供的四种基本类型过滤器接口,IAuthorizationFilter.IActionFilter.IResultFilter和IExceptionFilter,可通过继承对应的接口和Filt ...

  6. JavaScript & XML

    原文:JavaScript & XML 检测浏览器能力特性 //检测浏览器是否支持DOM2级XML var hasXmlDom = document.implementation.hasFea ...

  7. Swift-开发 # 1.2版本迁移

    { Parallels: 可以将一个win程序拖到mac中运行. } --类似于虚拟机 遇到的几大问题: 1.自动修改无效? --忽略它的存在,坑. 2.无止境的修改,还是错? --使用替换工具-&g ...

  8. poj 2828 Buy Tickets(树状数组 | 线段树)

    题目链接:poj 2828 Buy Tickets 题目大意:给定N,表示有个人,给定每一个人站入的位置,以及这个人的权值,如今按队列的顺序输出每一个人的权值. 解题思路:第K大元素,非常巧妙,将人入 ...

  9. Go as continuous delivery tool for .NET

    http://simon-says-architecture.com/2014/02/28/go-as-continuous-delivery-tool-for-net/ Following my p ...

  10. CentOS采用grub进 single状态

    当系统文件错误,有可能无法进入系统.或者您忘记了原来的系统password. 用这种方法可以,进single状态,编辑系统启动文件或更改的错误password. 1.重新启动系统. 2.按" ...