SharePoint 提供程序托管的外接程序中的跨域图像
在提供商托管的外接程序中跨域使用图像。
适用于:SharePoint 2013 | SharePoint 外接程序 | SharePoint Online
可能需要在提供程序托管加载项中显示 SharePoint 网站中的图像。由于提供程序托管加载项在远程 Web 上运行,因此提供程序托管加载项的域不同于 SharePoint 网站。 例如,加载项可能是在 Microsoft Azure 上运行,而尝试显示的图像则来自 Office 365。 由于提供程序托管加载项跨域访问图像,因此 SharePoint 要求必须有用户授权,才能在提供程序托管加载项中显示图像。
Core.CrossDomainImages 代码示例展示了提供程序托管加载项如何使用 SharePoint 访问令牌和 REST 服务从 SharePoint 检索图像。 REST 服务返回 Base64 编码的字符串,用于在浏览器中显示图像。 此示例中的解决方案可用于通过服务器端代码或客户端代码,在提供商托管加载项中显示 SharePoint 中存储的图像。
注意
由于此示例使用 REST 终结点,因此可以使用服务器端代码或客户端代码检索图像。
开始之前
若要开始,请从 GitHub 上的 Office 365 开发人员模式和做法(#office-365-开发人员模式和做法项目下载 Core.CrossDomainImages(#core.crossdomainimages) 示例外接程序。
使用 Core.CrossDomainImages 代码示例
运行此示例时,Default.aspx 将尝试加载以下内容:
图像 1,通过使用绝对 URL。
图像 2,通过对返回 Base64 编码的字符串的 REST 终结点使用服务器端调用。
图像 3(通过对返回 Base64 编码的字符串的 REST 终结点执行客户端调用)。
注意
图像 1 不会呈现,因为加载项跨域获取 SharePoint 中的图像。 请注意在 localhost 上运行的提供程序托管加载项的 URL。 打开图像 1 的快捷菜单(右键单击),再选择“属性”。 请注意,“地址(URL)”尝试从加载项 Web(而不是 localhost)检索图像。 由于提供程序托管加载项跨域访问加载项 Web,因此需要经过身份验证才能访问图像。 将“地址(URL)”复制并粘贴到新浏览器窗口中,确认直接访问图像 1 的 URL(而不是在提供程序托管加载项中执行跨域调用)能否进行解析,且不生成任何错误。 请注意,图像 1 显示,且没有生成任何错误。 比较图像 1 与图像 2 的源。 请注意,“地址(URL)”指向 Base64 编码的字符串。
Default.aspx 加载时,Page_Load 运行并执行以下操作:
将 Image1.ImageUrl 设置为图像的绝对路径。
实例化 ImgService。 ImgService 是运行在与提供商托管的外接程序相同的域中的 REST 终结点。
将 Image2.ImageUrl 设置为 ImgService.GetImage 返回的 Base64 编码的字符串。 访问令牌、网站、文件夹和文件名以参数的形式传递到 ImgService.GetImage。
注意
本文中的代码按原样提供,不提供任何明示或暗示的担保,包括对特定用途适用性、适销性或不侵权的默示担保。
protected void Page_Load(object sender, EventArgs e)
{
var spContext = SharePointContextProvider.Current.GetSharePointContext(Context);
using (var clientContext = spContext.CreateUserClientContextForSPAppWeb())
{
// Set the access token in a hidden field for client-side code to use.
hdnAccessToken.Value = spContext.UserAccessTokenForSPAppWeb;
// Set the URLs to the images.
Image1.ImageUrl = spContext.SPAppWebUrl + "AppImages/O365.png";
Services.ImgService svc = new Services.ImgService();
Image2.ImageUrl = svc.GetImage(spContext.UserAccessTokenForSPAppWeb, spContext.SPAppWebUrl.ToString(), "AppImages", "O365.png");
}
}
GetImage 执行以下操作:
使用 url 来存储将用于从 SharePoint 检索图像的 GetFolderByServerRelativeUrl REST 终结点 URI。 请参阅 文件和文件夹 REST API 引用(#文件和文件夹-rest-api-引用) 了解详细信息。
通过使用 url 实例化 HttpWebRequest(#httpwebrequest) 对象。
将授权标头添加到包含访问令牌的 HttpWebRequest 对象中。
对终结点 URI 执行了 GET 调用后,返回的数据流是 Base64 编码的字符串。 将返回的字符串设置为图像的 src 属性。
public string GetImage(string accessToken, string site, string folder, string file)
{
// Create the HttpWebRequest to call the REST endpoint.
string url = String.Format("{0}_api/web/GetFolderByServerRelativeUrl('{1}')/Files('{2}')/$value", site, folder, file);
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.Headers.Add("Authorization", "Bearer" + " " + accessToken);
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
using (var sourceStream = response.GetResponseStream())
{
using (var newStream = new MemoryStream())
{
sourceSteam.CopyTo(newStream);
byte[] bytes = newStream.ToArray();
return "data:image/png;base64, " + Convert.ToBase64String(bytes);
}
}
}
}
在 Page_Load 完成后,Default.aspx 运行自身包含的客户端代码,以加载图像 3。 客户端代码使用 jQuery Ajax 调用 GetImage。 当 GetImage 成功返回 Base64 编码的字符串时,图像 3 的 src 属性设置为返回的字符串。
...
$.ajax({
url: '../Services/ImgService.svc/GetImage?accessToken=' + $('#hdnAccessToken').val() + '&site=' + encodeURIComponent(appWebUrl + '/') + '&folder=AppImages&file=O365.png',
dataType: 'json',
success: function (data) {
$('#Image3').attr('src', data.d);
},
error: function (err) {
alert('error occurred');
}
});
...