gpt4 book ai didi

javascript - 写入 Google Spreadsheet API 时 CORS 预检失败

转载 作者:行者123 更新时间:2023-11-30 05:42:13 25 4
gpt4 key购买 nike

我正在开发一个使用 Google 电子表格的 JS 应用程序。我使用 OAuth 授权通过 REST 接口(interface)访问它们,当我坚持使用用于阅读的 GET 请求时,一切都很好。

我想使用显示的 API 添加新工作表 in the docs .这需要一个带有相当奇怪的 Content-type: application/atom+xmlPOST 请求,我喜欢这样 (JQuery):

$.ajax("https://spreadsheets.google.com/feeds/worksheets/{{key}}/private/full", {
type: "POST",
contentType: "application/atom+xml",
headers: { Authorization: "Bearer" + token },
data: data
});

由于 CORS 要求,这会使 Chrome 发出预检请求。预检 OPTIONS 请求失败 - Google 在响应中不包含 Access-Control-Allow-Origin header ,Chrome 拒绝继续:

OPTIONS https://spreadsheets.google.com/feeds/.../private/full 
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.

但是,如果我直接GET 到相同的 URL(这实际上是您阅读电子表格的方式),我获得访问控制-* header ,这意味着 CORS 支持是有意的。与标准内容类型(如 text/plain)的 POST 请求相同,不会触发预检 OPTIONS - 我得到 CORS header (即使请求对错误的内容类型失败)。

有没有人知道如何解决这个问题,或者从浏览器中“正确”地解决这个问题?或者,指向任何能够从浏览器内 JS 对 Google 电子表格执行“写入”操作的工作代码的指针也很棒。

我希望尽可能将此应用程序保留在客户端 - 我知道使用服务器端组件处理 Google API 交互,这件事会更容易。

最佳答案

别管我上面写了什么。这只能解决部分时间。似乎 Google Sheets API 根本不支持 CORS。我编写了一个服务器端代理,它只将请求传递给 google.com,这是唯一的前进方式。

我想我应该分享我的 js 代码,因为我写了一个很好的小东西,可以像 $.ajax 一样使用。也很高兴分享服务器端代码,但您可以使用类似这样的东西与您自己的服务器端代理进行交互。它不漂亮,但它正在工作。哦,嗯,​​LGPL。这是 js:

//  ####    ####   #####    ####     ##    ##   ##    ##   ##  ##
// ## ## ## ## ## ## ## #### ## ## #### ## ##
// ## ## ## ##### #### ## ## ## # ## ## ## ####
// ## ## ## ## ## ## ## ###### ####### ###### ##
// #### #### ## ## #### ## ## ## ## ## ## ##

function CorsAway(serverSideUrl) {
// Server-side proxy handling of cross-domain AJAX requests.
this.serverSideUrl = serverSideUrl;

// This hash contains information as to whether each $.ajax parameter should be submitted to $.ajax directly, or passed to the CorsAway server.
// true means that the parameter should be passed to the CorsAway server
this.parameterIsForRemoteServer = {
// accepts: // not supported
// async: // not supported
beforeSend: false, // submit to $.ajax
// cache: // not supported, see $.ajax documentation for how to implement
complete: false, // submit to $.ajax
contents: false, // submit to $.ajax
contentType: true, // submit to remote server
context: false, // submit to $.ajax
converters: false, // submit to $.ajax
// crossDomain: // not supported
data: true, // submit to remote server
dataFilter: false, // submit to $.ajax
dataType: false, // submit to $.ajax
error: false, // submit to $.ajax
// global: // not supported
headers: true, // submit to remote server
// ifModified: // not supported
// isLocal: // not supported
// jsonp: // not supported
// jsonpCallback: // not supported
method: true, // submit to remote server
/// mimeType: true, // submit to remote server
/// password: true, // submit to remote server
// processData: // REQUIRES SPECIAL HANDLING: SEE COMMENTS IN CODE BELOW
// scriptCharset: // not supported
statusCode: false, // submit to $.ajax
success: false, // submit to $.ajax
timeout: false, // submit to $.ajax
// traditional: // not supported
// type: // not supported
/// url: true, // submit to remote server
/// username: true // submit to remote server
// xhr: // not supported
// xhrFields: // not supported
}

// Use it just like $.ajax
this.ajax = function (url, jqAjaxInfo) {
//Redirect all requests to a call to the server

// Sort jqAjaxInfo into parameters for $.ajax and for the remote server
var localAjaxParams = {};
var remoteHttpRequestParams = {};
for(var k in jqAjaxInfo) {
if(this.parameterIsForRemoteServer[k]) {
// Submit it to the remote server
remoteHttpRequestParams[k] = jqAjaxInfo[k];
} else { // some parameters are not supported; their behavior is undefined and doesn't matter
// Submit it to $.ajax
localAjaxParams[k] = jqAjaxInfo[k];
}
}

// Prepare specially encapsulated data parameter for local $.ajax to submit to server-side CorsAway
localAjaxParams.data = {
dataToSubmit: localAjaxParams.data,
remoteHttpRequestParams: remoteHttpRequestParams,
remoteUrl: url
};
localAjaxParams.method = 'PUT'; // Always make request to CorsAway by PUT

// Make call to $.ajax and pass info to server-side CorsAway service
$.ajax(this.serverSideUrl, localAjaxParams);
}
}

// Instantiate global object with URL of server-side CorsAway service
window.corsAway = new CorsAway('/local/url/of/corsaway.php');

所以现在我使用 window.corsAway.ajax 而不是 $.ajax,结果完全相同。服务器端代理旨在从远程服务器返回数据,或将它收到的任何 HTML 错误传递回 ajax。

编写名为 CorsAway 的实用程序似乎有些不对劲,但是嘿。服务器端代理检查域并只将内容传递给批准的域(目前只有谷歌)所以可能会出错,对吧?有人告诉我是否出了什么问题。 :-)

关于javascript - 写入 Google Spreadsheet API 时 CORS 预检失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20169829/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com