2012-07-23 31 views
2

更新:这是GoogleDrive中的一个错误,CORS未启用上传URI。 @Nivco指示我使用Google的客户端库,它使用iframe和代理(而不是CORS)。我将(测试的)工作代码放在底部,并附有详细的解释。请参阅下面的示例中的答案。https://www.googleapis.com/upload/drive/v2/files是否真的支持CORS?

Inserting File to Google Drive through APIAuthorization of Google Drive using JavaScript表示上传端点支持CORS,但我一直无法使用它们。我可以使用Files: insert获得授权并插入空文件,但我无法上传内容 - 当我使用https://www.googleapis.com/upload/drive/v2/files时,如果使用示例中给出的两种技术中的任何一种,我会得到405(方法不允许)错误在插入文件堆栈溢出文章中。

CORS是否可以用于v1并且尚未启用v2?

编辑:顺便说一句,405错误是在铬制作的选项请求。

编辑:下面是从我的尝试之一代码:

之前,我提出我想强调的是,我能够进行身份验证和列表文件的代码。我只是无法将数据上传到文件。

var xhr = new XMLHttpRequest(); 
xhr.open('POST', 'https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart'); 
xhr.setRequestHeader('Authorization', 'Bearer ' + params.access_token); 
xhr.setRequestHeader("Content-Type", 'multipart/related; boundary="END_OF_PART"'); 
xhr.onreadystatechange = function(data) { 
    if (xhr.readyState == DONE) { 
    document.getElementById("files").innerHTML = "Uploaded file: " + xhr.responseText; 
    }; 
    } 
xhr.send([ 
    mimePart("END_OF_PART", "application/json", json), 
    mimePart("END_OF_PART", "text/plain", "a\nb\n"), 
    "\r\n--END_OF_PART--\r\n", 
].join('')); 
function mimePart(boundary, mimeType, content) { 
    return [ 
    "\r\n--", boundary, "\r\n", 
    "Content-Type: ", mimeType, "\r\n", 
    "Content-Length: ", content.length, "\r\n", 
    "\r\n", 
    content, 
    ].join(''); 
} 

这里是要求:

Request URL:https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart 
Request Method:OPTIONS 

这里是回应:

Status Code:405 Method Not Allowed 
cache-control:no-cache, no-store, must-revalidate 
content-length:0 
content-type:text/html; charset=UTF-8 
date:Mon, 23 Jul 2012 22:41:29 GMT 
expires:Fri, 01 Jan 1990 00:00:00 GMT 
pragma:no-cache 
server:HTTP Upload Server Built on Jul 17 2012 16:15:04 (1342566904) 
status:405 Method Not Allowed 
version:HTTP/1.1 

没有反应,因为Chrome浏览405错误对于OPTIONS请求。没有发布,因为浏览器无法继续,因为它的OPTIONS请求有405失败了,所以它打印在控制台此错误:

XMLHttpRequest cannot load https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart. Origin https://leisurestorage.appspot.com is not allowed by Access-Control-Allow-Origin. 
+0

您是否使用特定的浏览器?我尝试过使用Chrome,它对我来说非常合适。你有没有看过[google-apis-javascript-client](http://code.google.com/p/google-api-javascript-client/wiki/CORS)项目页面? – Alain 2012-07-23 21:36:16

+0

我试过Chrome和Firefox。我正在编辑我的原创以添加更多信息。 – 2012-07-23 22:32:23

+0

我添加了更多信息。我可以使用该技术进行身份验证并获取文件列表,但我无法使用它将数据上传到文件。 – 2012-07-23 22:52:36

回答

0

这个答案(实际上这个问题本身)现在冗余给予了充分的CORS支持由史蒂夫Bazyl证实

工作代码,使用@ Nivco的帮助下,有详细的解释和说明:

这里是这项技术全面测试的工作代码。要使用这个,你需要制作两页。第一页认证并启动第二页,这是您的实际应用程序。为了能够访问Google Drive API上传文件,您需要注册一个应用,该应用的描述为here

您的第一页将使用OAuth,这在this Stackoverflow answer中描述。

#access_token=ya29.AHES6ZSb4M4ju8U_X_zgFrz_MD2RsjrQu5V05HjsBtrCl0nh2SrnaA&token_type=Bearer&expires_in=3600 

在JavaScript中,您可以访问片段与location.hash:它有一个片段,看起来像这样调用你的应用程序。保存值后,最好将location.hash设置为空字符串,以便它不会显示在浏览器的位置栏中。您的应用程序需要使用CORS请求中片段的access_token值,以及代理(非CORS)请求中的上传API。下面是一个例子启动页,这实在是刚刚从OAuth的例子代码的版本:

<html> 
    <body> 
    <a href="javascript:poptastic('https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/drive.file&client_id=270759921607.apps.googleusercontent.com&redirect_uri=https://leisurestorage.appspot.com&response_type=token');">Authorize Leisure Storage</a><br> 
    <script> 
     function poptastic(url) { 
     var newWindow = window.open(url, 'name', 'height=600,width=450'); 
     if (window.focus) { 
      newWindow.focus(); 
     } 
     } 
    </script> 
    </body> 
</html> 

下面是一个例子应用程序,上传a\na\b\n到你的Google云端硬盘称为leisureUpload文件,使用谷歌的客户端JavaScript库。不需要使用任何gapi.auth方法,因为它直接在调用中使用带有Authorization头的原始gapi.client.request()调用,就像使用CORS的xmlHttpRequest()一样:

<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"> 
    <title>Leisure</title> 
    <script type="text/javascript"> 
    var hash = location.hash.substring(1).split('&'); 
    location.hash = ''; 
    var params = {}; 

    for (var i = 0; i < hash.length; i++) { 
     var p = hash[i].split('='); 

     params[p[0]] = p[1]; 
    } 
    function gapiClientLoaded() {/* do nothing */} 
    function uploadTestFile() { 
     var json = JSON.stringify({ 
      mimeType: 'text/plain', 
      title: 'leisureUpload', 
     }); 
     var xhr = new XMLHttpRequest(); 

     gapi.client.request({ 
      'path': '/upload/drive/v1/files', 
      'method': 'POST', 
      'params': {'uploadType': 'multipart'}, 
      'headers': { 
       'Content-Type': 'multipart/mixed; boundary="END_OF_PART"', 
       'Authorization': 'Bearer ' + params.access_token, 
      }, 
      'body': [ 
       mimePart("END_OF_PART", "application/json", json), 
       mimePart("END_OF_PART", "text/plain", "a\nb\n"), 
       "\r\n--END_OF_PART--\r\n", 
      ].join('') 
     }).execute(function(file) { 
      document.getElementById("result").innerHTML = "Uploaded file: " + file; 
     }); 
    } 
    function mimePart(boundary, mimeType, content) { 
     return [ 
      "\r\n--", boundary, "\r\n", 
      "Content-Type: ", mimeType, "\r\n", 
      "Content-Length: ", content.length, "\r\n", 
      "\r\n", 
      content, 
     ].join(''); 
    } 
    </script> 
    <script src="https://apis.google.com/js/client.js?onload=gapiClientLoaded"></script> 
    </head> 
    <body> 
    <h1>Welcome to Leisure!</h1> 
    <button onclick="uploadTestFile()">Upload Test File</button><br> 
    <pre id="result"></pre> 
    </body> 
</html> 
2

看来你是对的,上传API端点唐似乎不支持CORS请求,而其他端点支持它(抱歉没有完全测试)。这是一个错误,我们已经让我们的工程团队知道这个问题。

在平均时间似乎唯一的解决方法是使用JavaScript客户端库,并把它作为使用说明的IFRAME代理的优势,在Authorization of Google Drive using JavaScript

感谢提出这个问题!

+0

谢谢! 我会尝试。我打算尝试[http://developer.yahoo.com/yql/](YQL)作为上传API的替代方式 - 我认为它使用了类似的方法(通过服务器代理)。 YQL有什么原因不起作用? – 2012-07-24 14:34:33

+0

哎呀,得到的链接语法反向:)应该是[YQL](http://developer.yahoo.com/yql/)。 – 2012-07-24 14:59:19

+0

谢谢,@Nivco!我使用你指定给我的客户端库进行工作,并使用工作代码更新了该帖子。 – 2012-07-25 15:49:02