在微软的官方网站上有关于如何在SharePoint当中使用JS创建一个简单的文本文件的例子,经过我的思考我觉得结合Html5特性的浏览器,是完全可以通过JS来读取到文件的内容的(这一部分的内容请大家自行去了解),进而可以实现一个纯的JS的文件上传的例子,经过我的不断的实践,终于可以实现纯JS的文件上传了,当然还是参考了如下的文章。

限制有2个:

1、文件不能太大1.5MB以内完全是没有问题,这是JSOM的限制,没有办法突破。

2、浏览器必须是完全支持HTML5的,Chrome完全可以,IE必须11以上。

原理:使用FileReader来读取文件的Base64Url流,FileReader.readAsDataURL,然后使用自己写的把Base64的字符转成二进制的函数,把这个二进制的代码传给FileCreationInfomation.Content。

神奇的函数convertDataURIToBinary,我不知道是怎么工作的,如果有兴趣你来解释一下。

看如下的代码:

 $(document).ready(function ()
{
// Get the URI decoded host web URL
// We will use this to get a context here to write data
hostweburl = decodeURIComponent(getQueryStringParameter("SPHostUrl"));
}); function CreateFile()
{
// Ensure the HTML5 FileReader API is supported
if (window.FileReader)
{
input = document.getElementById("fileinput");
if (input)
{
file = input.files[0];
fr = new FileReader();
fr.onload = receivedBinary;
fr.readAsDataURL(file);
}
}
else
{
alert("The HTML5 FileSystem APIs are not fully supported in this browser.");
}
} // Callback function for onload event of FileReader
function receivedBinary()
{
// Get the ClientContext for the app web
clientContext = new SP.ClientContext.get_current();
// Use the host web URL to get a parent context - this allows us to get data from the parent
parentCtx = new SP.AppContextSite(clientContext, hostweburl);
parentWeb = parentCtx.get_web();
parentList = parentWeb.get_lists().getByTitle("Documents"); fileCreateInfo = new SP.FileCreationInformation();
fileCreateInfo.set_url(file.name);
fileCreateInfo.set_overwrite(true);
fileCreateInfo.set_content(new SP.Base64EncodedByteArray()); // Read the binary contents of the base 64 data URL into a Uint8Array
// Append the contents of this array to the SP.FileCreationInformation
var arr = convertDataURIToBinary(this.result);
for (var i = 0; i < arr.length; ++i)
{
fileCreateInfo.get_content().append(arr[i]);
} // Upload the file to the root folder of the document library
this.newFile = parentList.get_rootFolder().get_files().add(fileCreateInfo); clientContext.load(this.newFile);
clientContext.executeQueryAsync(onSuccess, onFailure);
} function onSuccess()
{
// File successfully uploaded
alert("Success!");
} function onFailure()
{
// Error occurred
alert("Request failed: " + arguments[1].get_message());
} // Utility function to remove base64 URL prefix and store base64-encoded string in a Uint8Array
// Courtesy: https://gist.github.com/borismus/1032746
function convertDataURIToBinary(dataURI)
{
var BASE64_MARKER = ';base64,';
var base64Index = dataURI.indexOf(BASE64_MARKER) + BASE64_MARKER.length;
var base64 = dataURI.substring(base64Index);
var raw = window.atob(base64);
var rawLength = raw.length;
var array = new Uint8Array(new ArrayBuffer(rawLength)); for (i = 0; i < rawLength; i++)
{
array[i] = raw.charCodeAt(i);
}
return array;
}

本文的原文如下:http://dannyjessee.com/blog/index.php/2013/02/using-jsom-to-write-small-files-to-a-sharepoint-2013-document-library/

A recent post on Yammer lamented the lack of examples in the SharePoint 2013 API documentation that use the JavaScript Object Model (JSOM) to do anything more than create a very basic text file in a SharePoint document library.

After lots of digging and a fair amount of trial and error, I now understand why that is the case.

The use case seems simple enough: allow the user to select a file from his or her local machine using an HTML DOM FileUpload object on a form, then use JSOM to upload this file into a document library. It’s certainly easy enough to do using the Client Script Object Model (CSOM). As it turns out, there are a couple of very good reasons why your document upload capability (whether you package it into an app for SharePoint or something else) should NOT leverage JSOM:

  • Per MSDN, you can only work with files up to 1.5 MB when using JSOM. It is recommended that you use REST to deal with larger files. (Incidentally, there is a comment in the article on using the REST endpoints that reads “See How to: Complete basic operations using JavaScript library code in SharePoint 2013 for a code example that shows you how to upload a binary file that is smaller than 1.5 MB by using the SharePoint 2013 Javascript object model.” Unfortunately, the only code example in that article creates a very rudimentary plain text file.)
  • Unless your browser supports the File APIs introduced in HTML5 (specifically the FileReader API), you are out of luck. As a general rule, browsers will block attempts by JavaScript to access and read files from the local file system for security reasons. If you are using IE, only version 10 supports the FileReader API.

Although I was somewhat discouraged by this news, I was determined to develop an app for SharePoint 2013 that presented a simple file upload control to the user and stored the file in a document library (as long as it was smaller than 1.5 MB, of course). I figured as long as I could save Office documents to the library (i.e., more than a simple plain text file), I would have succeeded.

To accomplish this, I knew I would need to make use of the HTML5 FileReader API. (Because of that, I also knew I would need to test this solution using IE 10, Firefox, or Chrome!) Based on the MSDN documentation, I knew I would be setting the contents of the file by using a newSP.Base64EncodedByteArray. The FileReader API exposes three methods for reading the contents of a file:

  1. readAsText() – this method reads the plain text contents of a file, but does not properly handle binary files.
  2. readAsArrayBuffer() – this seemed to be the most promising option, but no matter how I tried to cast the contents of the ArrayBuffer to a Base64-encoded byte array, I was not able to successfully reproduce a file from the file system in a document library. If anyone out there has any suggestions that might enable readAsArrayBuffer() to work, please let me know in the comments!
  3. readAsDataURL() – this method returns the contents of the file using the Data URI scheme. Thanks to a handy utility method I found here, I can convert this Base64-encoded string into a JavaScript Uint8Array and use that to populate the SP.Base64EncodedByteArray that the JSOM expects.
 $(document).ready(function ()
{
// Get the URI decoded host web URL
// We will use this to get a context here to write data
hostweburl = decodeURIComponent(getQueryStringParameter("SPHostUrl"));
}); function CreateFile()
{
// Ensure the HTML5 FileReader API is supported
if (window.FileReader)
{
input = document.getElementById("fileinput");
if (input)
{
file = input.files[0];
fr = new FileReader();
fr.onload = receivedBinary;
fr.readAsDataURL(file);
}
}
else
{
alert("The HTML5 FileSystem APIs are not fully supported in this browser.");
}
} // Callback function for onload event of FileReader
function receivedBinary()
{
// Get the ClientContext for the app web
clientContext = new SP.ClientContext.get_current();
// Use the host web URL to get a parent context - this allows us to get data from the parent
parentCtx = new SP.AppContextSite(clientContext, hostweburl);
parentWeb = parentCtx.get_web();
parentList = parentWeb.get_lists().getByTitle("Documents"); fileCreateInfo = new SP.FileCreationInformation();
fileCreateInfo.set_url(file.name);
fileCreateInfo.set_overwrite(true);
fileCreateInfo.set_content(new SP.Base64EncodedByteArray()); // Read the binary contents of the base 64 data URL into a Uint8Array
// Append the contents of this array to the SP.FileCreationInformation
var arr = convertDataURIToBinary(this.result);
for (var i = 0; i < arr.length; ++i)
{
fileCreateInfo.get_content().append(arr[i]);
} // Upload the file to the root folder of the document library
this.newFile = parentList.get_rootFolder().get_files().add(fileCreateInfo); clientContext.load(this.newFile);
clientContext.executeQueryAsync(onSuccess, onFailure);
} function onSuccess()
{
// File successfully uploaded
alert("Success!");
} function onFailure()
{
// Error occurred
alert("Request failed: " + arguments[1].get_message());
} // Utility function to remove base64 URL prefix and store base64-encoded string in a Uint8Array
// Courtesy: https://gist.github.com/borismus/1032746
function convertDataURIToBinary(dataURI)
{
var BASE64_MARKER = ';base64,';
var base64Index = dataURI.indexOf(BASE64_MARKER) + BASE64_MARKER.length;
var base64 = dataURI.substring(base64Index);
var raw = window.atob(base64);
var rawLength = raw.length;
var array = new Uint8Array(new ArrayBuffer(rawLength)); for (i = 0; i < rawLength; i++)
{
array[i] = raw.charCodeAt(i);
}
return array;
}
 

This code works!–mostly. In my environment, Excel Services was able to successfully open my basic test spreadsheet in the browser:

I could also use the Download a Copy option to save local copies and successfully open files of any type:

 

For a simple Word document, though, I was unable to click the link from the document library and have it open successfully in Word. Instead, Word reported an error when trying to open the document:

If you receive the error shown below when opening a document from SharePoint, it is due to “Protected View” in Office 2013. To disable Protected View, follow the steps outlined here.

Regardless of your Office 2013 Protected View settings, the Download a Copy option will open the document without the annoying error message.

 

如何在SharePoint 当中使用纯JSOM上传任意二进制文件(小于2MB)的更多相关文章

  1. ItunesConnect:上传完二进制文件后在构建版本中找不到

    最近经常遇到上传完二进制文件后在构建版本中找不到的情况: 环境:Xcode 8.2 (8C38) 大致有几种原因,可以按照以下步骤排查下. 排查步骤: 1.检查使用的权限,并info.plist文件中 ...

  2. IIS 6.0 PUT上传 任意文件创建漏洞

    IIS 6.0 PUT上传 任意文件创建漏洞 require 1.IIS Server在Web服务扩展中开启了WebDAV. 2.IIS配置了可以写入的权限,包括网站 1.根目录 2.子文件夹 3.i ...

  3. 利用servlet3.0上传,纯原生上传,不依赖任何第三方包

    tomcat7里面自带的servlet3.0.jar,支持很多新特性,例如,annotation配置servlet,上传,异步等等.... 如果你的tomcat版本低于7的话,单独在项目中引入serv ...

  4. 纯js上传控件——fineuploader

    fineuploader是一款基于ajax实现文件上传的插件,具有以下有点: A:支持文件上传进度显示. B:文件拖拽浏览器上传方式 C:Ajax页面无刷新. D:多文件上传. F:跨浏览器. E:跨 ...

  5. 如何在linux下使用git管理上传代码&误删文件修复

    首先需要安装git,sudo apt-get install git,这时就可以下载代码了. 然后先在gituhub上新建一个仓库,然后先在本地建一个git目录,git init 然后再配置用户名和邮 ...

  6. 纯js上传文件 很好用

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...

  7. fromdata上传文件,ajax上传文件, 纯js上传文件,html5文件异步上传

    前端代码: 上传附件(如支付凭证等) <input type="file" name="fileUpload" id="fileUpload&q ...

  8. SpringBoot上传任意文件功能的实现

    一.pom文件依赖的添加 <dependencies> <dependency> <groupId>org.springframework.boot</gro ...

  9. SharePoint Server 2013 让上传文件更精彩

    新版的SharePoint 2013 提供了多种上传与新建文件的方式,对于与系统集成紧密的IE来上传文档更加方便 使用IE开启SharePoint地址 Figure 1打开文档库,在"新颖快 ...

随机推荐

  1. Linux系统中的Device Mapper学习

    在linux系统中你使用一些命令时(例如nmon.iostat 如下截图所示),有可能会看到一些名字为dm-xx的设备,那么这些设备到底是什么设备呢,跟磁盘有什么关系呢?以前不了解的时候,我也很纳闷. ...

  2. TFS 生成配置

      生成  

  3. mono for android学习过程系列教程(4)

    今天要讲的事情是构建安卓程序的UI界面. 首先给大家上点小点心,如图: 上面就是我们界面的设计模块,仔细看中间大块的下方,有一个Source,这就类似webform里面的设计和源代码界面. 在这个页面 ...

  4. 判断一个对象是jQuery对象还是DOM对象

    今天调试一段代码的时候,看到其中一个变量,想知道它到底是jquery对象还是dom对象. 虽然直接console出这个对象,看它的内部可以判断出来.但是我想有没有什么更方便的方法呢. 后来我想到了一个 ...

  5. 【深入浅出jQuery】源码浅析2--奇技淫巧

    最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...

  6. Lesson 24 It could be worse

    Text I entered the hotel manager's office and sat down. I had just lost £50 and I felt very upset. ' ...

  7. Java Spring mvc 操作 Redis 及 Redis 集群

    本文原创,转载请注明:http://www.cnblogs.com/fengzheng/p/5941953.html 关于 Redis 集群搭建可以参考我的另一篇文章 Redis集群搭建与简单使用 R ...

  8. 学习WCF入门的第一个实例

    一.概述 WCF说白了就是一个基于终结点的通信手段!就是Service端提供一定的功能实现,然后暴露出一个或多个终结点,Client端调用Service端的功能(可以理解为调用一个函数),那么Clie ...

  9. ASP.NET MVC5+EF6+EasyUI 后台管理系统(40)-精准在线人数统计实现-【过滤器+Cache】

    系列目录 上次的探讨没有任何结果,我浏览了大量的文章和个别系统的参考!决定用Cache来做,这可能有点难以接受但是配合mvc过滤器来做效果非常好! 由于之前的过滤器我们用过了OnActionExecu ...

  10. 【前端安全】JavaScript防http劫持与XSS

    作为前端,一直以来都知道HTTP劫持与XSS跨站脚本(Cross-site scripting).CSRF跨站请求伪造(Cross-site request forgery).但是一直都没有深入研究过 ...