同域内不同主机调用SharePoint 2013/2016 REST API方案咨询
我之前处理过不少SharePoint 2013/2016的跨域REST调用问题,针对你说的同域不同主机(比如同属domain.com下的serverA和serverB)的场景,有几个靠谱的解决方案,你可以根据自己的环境和需求选择:
方案1:修改SharePoint服务器的web.config配置CORS
因为SharePoint 2013/2016本身没有内置CORS支持,需要手动修改Web应用的web.config文件来添加CORS响应头。注意:修改web.config前一定要备份!
具体步骤:
- 找到SharePoint Web应用对应的
web.config文件(通常在C:\inetpub\wwwroot\wss\VirtualDirectories\<端口号>下) - 在
<system.webServer>节点下添加以下配置:
<httpProtocol> <customHeaders> <!-- 允许指定的同域主机,多个可以用逗号分隔,或者用*允许所有(不建议生产环境用*) --> <add name="Access-Control-Allow-Origin" value="http://serverB.domain.com" /> <add name="Access-Control-Allow-Methods" value="GET,POST,PUT,DELETE,OPTIONS" /> <add name="Access-Control-Allow-Headers" value="Content-Type, Accept, X-RequestDigest" /> <add name="Access-Control-Allow-Credentials" value="true" /> </customHeaders> </httpProtocol>
- 保存文件后,IIS会自动重启应用池,此时你的AJAX请求应该就能正常调用了。
方案2:使用SharePoint代理页面
如果不想修改web.config(比如没有服务器权限),可以在SharePoint站点中创建一个ASPX代理页面,前端先请求这个代理页面,再由代理页面去调用REST API,这样就绕开了CORS限制(因为代理和SharePoint是同主机)。
代理页面示例(Proxy.aspx):
<%@ Page Language="C#" %> <%@ Import Namespace="System.Net" %> <%@ Import Namespace="System.IO" %> <script runat="server"> protected void Page_Load(object sender, EventArgs e) { string restUrl = Request.QueryString["url"]; if (!string.IsNullOrEmpty(restUrl)) { try { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(restUrl); request.Method = Request.HttpMethod; // 传递请求头 foreach (string header in Request.Headers) { if (!header.Equals("Host", StringComparison.OrdinalIgnoreCase) && !header.Equals("Connection", StringComparison.OrdinalIgnoreCase)) { request.Headers.Add(header, Request.Headers[header]); } } // 传递请求体 if (Request.HttpMethod.Equals("POST", StringComparison.OrdinalIgnoreCase) || Request.HttpMethod.Equals("PUT", StringComparison.OrdinalIgnoreCase)) { using (Stream requestStream = request.GetRequestStream()) { Request.InputStream.CopyTo(requestStream); } } // 获取响应 using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { // 设置响应头 foreach (string header in response.Headers) { Response.Headers.Add(header, response.Headers[header]); } Response.StatusCode = (int)response.StatusCode; // 传递响应体 using (Stream responseStream = response.GetResponseStream()) { responseStream.CopyTo(Response.OutputStream); } } } catch (WebException ex) { // 处理错误 using (HttpWebResponse errorResponse = (HttpWebResponse)ex.Response) { Response.StatusCode = (int)errorResponse.StatusCode; using (Stream errorStream = errorResponse.GetResponseStream()) { errorStream.CopyTo(Response.OutputStream); } } } } } </script>
前端AJAX调用示例:
$.ajax({ url: "http://serverA.domain.com/sites/yourSite/Proxy.aspx?url=http://serverA.domain.com/sites/yourSite/_api/web/lists", method: "GET", headers: { "Accept": "application/json;odata=verbose" }, success: function(data) { console.log(data); }, error: function(error) { console.log(error); } });
方案3:使用SP.RequestExecutor.js脚本
SharePoint提供了SP.RequestExecutor.js这个脚本,专门用于跨域(包括同域不同主机)调用REST API,适合前端场景。
使用步骤:
- 先加载
SP.RequestExecutor.js脚本(通常在_layouts/15/SP.RequestExecutor.js路径) - 编写调用代码:
// 初始化RequestExecutor,参数是SharePoint站点的URL var executor = new SP.RequestExecutor("http://serverA.domain.com/sites/yourSite"); executor.executeAsync({ url: "_api/web/lists", method: "GET", headers: { "Accept": "application/json;odata=verbose" }, success: function(data) { var result = JSON.parse(data.body); console.log(result); }, error: function(error) { console.log(error); } });
这个脚本会自动处理跨域请求的细节,不需要额外配置服务器,比较适合前端开发者使用。
内容的提问来源于stack exchange,提问作者Alberto S.
相关产品推荐
相关产品推荐

