Jquery 将Infopath附件上载到Sharepoint

Jquery 将Infopath附件上载到Sharepoint,jquery,sharepoint,file-upload,infopath,Jquery,Sharepoint,File Upload,Infopath,在我见过的将infopath中的附件上载到sharepoint库的极少数方法中,没有一种看起来非常简单,而且都涉及服务器端代码。我从所有这些信息中了解到,该文件存储在表单的xml模板中,以base64加密 我拥有对sharepoint页面上表单DOM的完整javascript/jQuery访问权限,但我很难找到这个base64字符串的确切位置 注意,我试图在提交表单之前获取附件的base64,我假设它在DOM中的某个位置,但我不知道在哪里。非常感谢您的帮助。首先,请确保您没有将InfoPath文

在我见过的将infopath中的附件上载到sharepoint库的极少数方法中,没有一种看起来非常简单,而且都涉及服务器端代码。我从所有这些信息中了解到,该文件存储在表单的xml模板中,以base64加密

我拥有对sharepoint页面上表单DOM的完整javascript/jQuery访问权限,但我很难找到这个base64字符串的确切位置


注意,我试图在提交表单之前获取附件的base64,我假设它在DOM中的某个位置,但我不知道在哪里。非常感谢您的帮助。

首先,请确保您没有将InfoPath文档的XML DOM与HTML页面的HTML DOM混合使用

第二,在谈到InfoPath时:“XML模板”是存储在XSN中的XML,用作此XSN表单的初始(空白)文档。因为您说的是“在表单提交之前”,所以我假设您实际上是在谈论用这个XSN创建的XML文档(表单)

可以使用JavaScript直接向存储在文档库中的InfoPath XML文档添加附件(从服务器打开XML,替换节点的值,然后将其保存回去)。代码将比C#/VB.Net中的服务器端代码稍微复杂一些,因此。。。使用XPath或JQuery查找节点应该不太难,但它是特定于表单的

另外,我认为您正试图通过对页面的HTML呈现进行黑客攻击,来改变目前使用Forms Server打开的XML。我不会这样做:

  • 当Forms Server呈现表单时,浏览器中没有XML
  • 附件根本不会发送到HTML页面
  • 没有足够的人可以帮你
  • 这显然是不受支持的

我找到了一个使用jQuery和C代码隐藏页面的解决方案。以下是jQuery部分:

$.getJSON('_vti_bin/listdata.svc/<NAME OF LIST (FORMATTED FOR LISTDATA.SVC)>', function(data){
  $.each(data.d.results, function(index, value){
    $.get('<NAME OF LIST>/'+value.Title+"?noredirect=true", function(info){
      $.post('<PATH TO filecreator.aspx>, {file: $(info).find('[nodeName="my:memo"]').text()}, function(data){
        $('#response').html(data);
      });
    });
  });
});
$.getJSON(“\u vti\u bin/listdata.svc/”,函数(数据){
$。每个(数据d.结果、函数(索引、值){
$.get('/'+value.Title+“?noredirect=true”,函数(信息){
$.post(',{file:$(info).find('[nodeName=“my:memo”]').text()},函数(数据){
$('#response').html(数据);
});
});
});
});
html是一个非常简单的
,只是用来接收数据

以下是filecreator.aspx文件:

<%@ Page Language="C#" %>
<%@ Import Namespace="System.Web" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Text" %>
<script runat="server">
  public void Page_Load(object sender, EventArgs e){
    int fileSize, nameLength;
    string name = "";
    byte[] decodedData;
    HttpContext c = HttpContext.Current;
    string data64 = c.Request["file"];
    if(data64==""){
      return;
    }
    byte[] data = Convert.FromBase64String(data64);
    using(MemoryStream ms = new MemoryStream(data)){
      BinaryReader reader = new BinaryReader(ms);
      byte[] header = new byte[16];
      header = reader.ReadBytes(header.Length);

      fileSize = (int)reader.ReadUInt32();
      nameLength = (int)reader.ReadUInt32() * 2;

      byte[] fileName = reader.ReadBytes(nameLength);
      Encoding enc = Encoding.Unicode;
      name = enc.GetString(fileName, 0, nameLength -2);
      decodedData = reader.ReadBytes(fileSize);
    }
    string filePath = Server.MapPath("/temp/"+name);
    if(File.Exists(filePath)){
        File.Delete(filePath);
    }
    FileStream fs = new FileStream(filePath, FileMode.CreateNew);
    BinaryWriter writer = new BinaryWriter(fs);
    writer.Write(decodedData);

    writer.Close();
    fs.Close();
    Response.Write("<a href=\"http://sharept03sb1/services/?download.aspx?file="+name+"\">"+name+"</a><br />");
  }
</script>

公共无效页面加载(对象发送方,事件参数e){
int fileSize,nameLength;
字符串名称=”;
字节[]解码数据;
HttpContext c=HttpContext.Current;
字符串data64=c.Request[“file”];
如果(数据64==“”){
返回;
}
字节[]数据=Convert.FromBase64String(数据64);
使用(MemoryStream ms=新的MemoryStream(数据)){
BinaryReader=新的BinaryReader(毫秒);
字节[]头=新字节[16];
header=reader.ReadBytes(header.Length);
fileSize=(int)reader.ReadUInt32();
nameLength=(int)reader.ReadUInt32()*2;
字节[]文件名=reader.ReadBytes(名称长度);
Encoding enc=Encoding.Unicode;
name=enc.GetString(文件名,0,名称长度-2);
decodedData=reader.ReadBytes(文件大小);
}
字符串filePath=Server.MapPath(“/temp/”+name);
if(File.Exists(filePath)){
File.Delete(文件路径);
}
FileStream fs=newfilestream(filePath,FileMode.CreateNew);
BinaryWriter=新的BinaryWriter(fs);
writer.Write(解码数据);
writer.Close();
fs.Close();
响应。写入(“
”); }
最后,这是开始下载的download.aspx文件,它现在易受lfi攻击,我将标记应该修复的位置:

<%@ Page Language="C#" %>
<%@ Import Namespace="System.Web" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Text" %>
<script runat="server">
  public void Page_Load(object sender, EventArgs e){
    string name = Request.QueryString["file"]; // HERE: Make sure to prevent lfi via directory traversal :)
    FileStream fs = File.Open(Server.MapPath("/temp/"+name), FileMode.Open);
    byte[] file = new byte[fs.Length];
    fs.Read(file, 0, Convert.ToInt32(fs.Length));
    fs.Close();
    Response.AddHeader("Content-disposition", "attachment; filename=" + name);
    Response.ContentType = "application/octet-stream";
    Response.BinaryWrite(file);
    Response.End();
  }
</script>

公共无效页面加载(对象发送方,事件参数e){
string name=Request.QueryString[“file”];//此处:确保通过目录遍历防止lfi:)
FileStream fs=File.Open(Server.MapPath(“/temp/”+name),FileMode.Open);
字节[]文件=新字节[fs.Length];
读取(文件,0,Convert.ToInt32(fs.Length));
fs.Close();
Response.AddHeader(“内容处置”、“附件;文件名=“+name”);
Response.ContentType=“应用程序/八位字节流”;
BinaryWrite(文件);
Response.End();
}
以下几点提示:

  • 如果您听到一些关于代码块不起作用的言论,请确保对sharepoint的web.config文件中的PageParserPath进行一些研究。你需要改变这一点
  • 这仅为包含infopath表单的文档库中的每个附件提供下载链接。当然,您可以使用参数化查询来过滤某些数据

事实上,我找到了一种比任何提议的方法都要好得多的方法,我是否应该把它作为这个问题的答案发布出来?