使用 ColdFusion 将文件上传到 Google Drive

Posted

技术标签:

【中文标题】使用 ColdFusion 将文件上传到 Google Drive【英文标题】:Upload Files To Google Drive Using ColdFusion 【发布时间】:2012-12-16 23:06:40 【问题描述】:

*为更好的第二部分进行了新更新 - 现在进入“308 Resume Incomplete”,即使文件应该只是一个上传!

我正在使用 Ray Camden 的 cfgoogle 的基础。但是谷歌已经弃用了文件上传的代码。新标准是Resumable Media Uploads。

我在上面引用的 Google 文档中让这部分工作(直到并包括“发起可恢复的上传请求”)。

调用页面:

<cfset application.cfc.Google                   = createObject('component','#path_cf_cfc#Google') />
<cfset application.cfc.GoogleDocs               = createObject('component','#path_cf_cfc#GoogleDocs') />

<cfset gtoken = application.cfc.GoogleDocs.authenticate(emailaddress,password)>

<CFSET testdoc = "a\filepath\documentname.doc">
<CFSET FileType = "application/msword">
<CFSET FileTitle = "test_001">

<cfset temp = application.cfc.GoogleDocs.upload_auth("#Application.Map.DocStorage##tv.testdoc#",FileType,FileTitle)>  

<CFSET uploadpath = Listgetat(Listgetat(temp.header,ListContains(temp.header,"https://docs.google.com","#chr(10)#"),"#chr(10)#"),2," ") >  

<cfset temp2 = application.cfc.GoogleDocs.upload_file("#Application.Map.DocStorage##tv.testdoc#",FileType,FileTitle,uploadpath)>

代码在cfset 临时行(获取唯一的上传 URI)之前有效并包括在内(获取唯一的上传 URI)

这里是upload_auth的代码:

<cffunction name="upload_auth" access="public" returnType="any" hint="I get a uniqu URI from Google API." output="false">
<cfargument name="myFile" type="string" required="true" hint="filepath to upload.">
<cfargument name="myType" type="string" required="true" hint="application/msword"> 
<cfargument name="myTitle" type="string" required="true" hint="name of doc"> 

<cfset GoogleUrl = "https://docs.google.com/feeds/upload/create-session/default/private/full">
<cfset GoogleVersion = 3> 
<cfset FileSize = createObject("java","java.io.File").init(myFile).length()>

<cfhttp url="#GoogleUrl#" method="post" result="diditwork" resolveurl="no">
<cfhttpparam type="header" name="Authorization" value="GoogleLogin auth=#getAuth(variables.docservice)#">
<cfhttpparam type="header" name="GData-Version" value="#GoogleVersion#">
<cfhttpparam type="header" name="Content-Length" value="0">
<cfhttpparam type="header" name="X-Upload-Content-Type" value="#myType#">
<cfhttpparam type="header" name="X-Upload-Content-Length" value="#FileSize#">
<cfhttpparam type="header" name="Slug" value="#myTitle#">

</cfhttp>

<cfreturn diditwork>
</cffunction>

好的 - 到目前为止一切顺利。 但这里是它崩溃的地方:

运行 upload_file 从 Google 返回“308 Resume Incomplete”(以免不是 400!)。啊!!

这里是upload_file -

<cffunction name="upload_file" access="public" returnType="any" hint="I upload the document." output="false">
<cfargument name="myFile" type="string" required="true" hint="filepath to upload.">
<cfargument name="myType" type="string" required="true" hint="like application/msword"> 
<cfargument name="myTitle" type="string" required="true" hint="name of doc"> 
<cfargument name="myAuthPath" type="string" required="true" hint="call auth"> 

<cfset FileSize = GetFileInfo(myFile).size >
<CFSET tv.tostartwithzero = FileSize - 1>

<CFFILE action="read" file="#myfile#" variable="FileText">

<cfhttp url="#myAuthPath#" method="put" result="diditwork" resolveurl="no" multipart="yes" charset="utf-8" >
<cfhttpparam type="header" name="Authorization" value="GoogleLogin auth=#getAuth(variables.docservice)#">
<cfhttpparam type="header" name="GData-Version" value="#variables.GoogleVersion#">
<cfhttpparam type="header" name="Content-Length" value="#FileSize#">
<cfhttpparam type="header" name="Content-Range" value="bytes 0-#tv.tostartwithzero#/#FileSize#">
<cfhttpparam type="header" name="Content-Type" value="#myType#">

<cfhttpparam type="body" value="#trim(FileText)#">

</cfhttp>

<cfreturn diditwork>
</cffunction>

所以,我们有它 - 我被卡住了。 我可以获得唯一的 URI,但是(可能是因为是深夜)我对自己做错的事情已经脑死了,否则要完成文件上传。

感谢所有帮助。

【问题讨论】:

我注意到,在内容范围标题中,您使用文件大小作为从磁盘读取的文件大小,但在正文中,您发送的是 trim(FileText),这意味着如果文件包含前导或尾随空格,请求正文大小将小于您声称发送的大小。您可以尝试使用 len(trim(FileText)) 来计算您在 content-range 和 content-length 标头中发送的范围和大小? 您也可以尝试执行 FileReadBinary 并将其发送到请求正文中,除非有理由修剪文件内容 您解决了吗?找到以下here。 在接收到恢复请求的内容正文后,服务器可能仍不拥有完整的字节范围,需要客户端采取进一步的行动(例如额外的请求)。在这种情况下,如果服务器仍然愿意继续操作,则应该返回状态码 308(Resume Incomplete)。 根据定义,308(Resume Incomplete)响应表示客户端可以纠正当前通过发送服务器丢失的字节的错误条件 【参考方案1】:

我强烈建议在这里采取不同的方法。你走的路有两个大问题:

看来代码正在使用已弃用的客户端登录身份验证机制,并且正在使用用户名/密码而不是 OAuth。 使用已弃用的文档列表 API 而不是较新的 Drive API。

由于您可以调用 java,我建议您使用纯 Java 编写上传代码,然后根据需要从您的 CF 页面调用它。

【讨论】:

以上是关于使用 ColdFusion 将文件上传到 Google Drive的主要内容,如果未能解决你的问题,请参考以下文章

Coldfusion调整大小使图像文件更大?

ColdFusion中的Wrap功能是否插入CR / LF?

如何在ColdFusion中上传图像文件后存储图像文件

使用 SSIS 将本地文件上传到谷歌云存储桶

如何正确使用 Coldfusion File Exist() 方法?

ColdFusion无法读取Ajax发送的FormData