https://www.googleapis.com/upload/drive/v2/files 真的支持 CORS 吗? [英] Does https://www.googleapis.com/upload/drive/v2/files really support CORS?

查看:21
本文介绍了https://www.googleapis.com/upload/drive/v2/files 真的支持 CORS 吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:这是 GoogleDrive 中的一个错误,没有为上传 URI 启用 CORS.@Nivco 向我指出了使用 iframe 和代理(不是 CORS)的 Google 客户端库的解决方法.我将(经过测试的)工作代码放在底部,并附有详细说明.请参阅下面的示例.

Update: This is a bug in GoogleDrive, CORS is not enabled for upload URIs. @Nivco pointed me to a work around with Google's client library which uses an iframe and a proxy (not CORS). I'm putting the (tested) working code at the bottom, along with a detailed explanation. Please see the answer, below for the example.

通过 API 将文件插入 Google DriveAuthorization of Google Drive using JavaScript 说上传端点支持CORS,但我没有能够使用它们.我可以使用 Files: insert 获得授权并插入一个空文件,但我无法将内容上传到其中 - 使用 https://www.googleapis.com/upload/drive/v2/files 当我使用插入文件堆栈溢出帖子中示例中给出的两种技术之一时.

Inserting File to Google Drive through API and Authorization of Google Drive using JavaScript say that the upload endpoints support CORS, but I haven't been able to use them. I can get authorization and insert an empty file, using Files: insert, but I can't upload content to it -- I get a 405 (Method not allowed) error when I use https://www.googleapis.com/upload/drive/v2/files when I use either of the two techniques given in the example in the inserting file stack overflow post.

CORS 是否可能适用于 v1 而尚未启用 v2?

Is it possible that CORS worked for v1 and hasn't been enabled for v2?

顺便说一句,405 错误出现在 chrome 正在发出的 OPTIONS 请求中.

By the way, the 405 error is on the OPTIONS request that chrome is making.

这是我的一次尝试中的代码:

Here's the code from one of my attempts:

在展示代码之前,我想强调一下我能够验证和列出文件.我就是无法将数据上传到文件中.

Before I present the code I want to highlight that I am able to authenticate and list files. I just can't upload data to a file.

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
b
"),
  "
--END_OF_PART--
",
].join(''));
function mimePart(boundary, mimeType, content) {
  return [
    "
--", boundary, "
",
    "Content-Type: ", mimeType, "
",
    "Content-Length: ", content.length, "
",
    "
",
    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 收到该 OPTIONS 请求的 405 错误.没有 POST,因为 Chrome 无法继续,因为它的 OPTIONS 请求失败并返回 405,因此它在控制台中打印此错误:

There is no response, because Chrome gets a 405 error for that OPTIONS request. There is no POST, because Chrome can't proceed, since its OPTIONS request failed with a 405, and so it prints this error in the console:

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.

推荐答案

这个答案(实际上是问题本身)现在是多余的,因为 Steve Bazyl 证实了完全的 CORS 支持

工作代码,使用@Nivco 的帮助,以及详细解释:

Working code, using @Nivco's help, along with detailed explanation:

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

Here is the working code for a full test of this technique. To use this, you need to make two pages. The first page authenticates and launches the second page, which is your actual app. In order to be able to access the Google Drive API to upload a file, you need to register an app, which is described here.

您的第一个页面将使用 OAuth,this Stackoverflow answer 中对此进行了描述.它使用如下所示的片段调用您的应用:

Your first page will use OAuth, which is described in this Stackoverflow answer. It calls your app with a fragment that looks like this:

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

在 JavaScript 中,您可以使用 location.hash 访问该片段.保存该值后,最好立即将 location.hash 设置为空字符串,这样它就不会显示在浏览器的位置栏中.您的应用程序需要在其 CORS 请求以及对上传 API 的代理(非 CORS)请求中使用片段中的 access_token 值.这是一个示例启动页面,它实际上只是 OAuth 示例代码的一个版本:

In JavaScript, you can access that fragment with location.hash. After you save the value, it's a good idea to set location.hash to the empty string right away, so that it doesn't show up in the browser's location bar. Your app needs to use the value of access_token from the fragment in its CORS requests and also in the proxied (non-CORS) request to the upload API. Here is an example launch page, which is really just a version of the code from OAuth example:

<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>

这是一个示例应用,它使用 Google 的 JavaScript 客户端库将 a a 上传到您的 GoogleDrive 中名为 leisureUpload 的文件中.不需要使用任何 gapi.auth 方法,因为它直接在调用中使用带有 Authorization 标头的原始 gapi.client.request() 调用,就像使用 CORS 使用 xmlHttpRequest() 一样:

Here is an example app that uploads a a to a file called leisureUpload in your GoogleDrive, using Google's Client Library for JavaScript. There is no need to use any of the gapi.auth methods, because it uses a raw gapi.client.request() call with the Authorization header directly in the call, just like it would with xmlHttpRequest() using CORS:

<!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
b
"),
                "
--END_OF_PART--
",
            ].join('')
        }).execute(function(file) {
            document.getElementById("result").innerHTML = "Uploaded file: " + file;
        });
    }
    function mimePart(boundary, mimeType, content) {
        return [
            "
--", boundary, "
",
            "Content-Type: ", mimeType, "
",
            "Content-Length: ", content.length, "
",
            "
",
            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>

这篇关于https://www.googleapis.com/upload/drive/v2/files 真的支持 CORS 吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆