使用 GET 从 Angular 6 到 Google Apps 脚本的 CORS 问题

Posted

技术标签:

【中文标题】使用 GET 从 Angular 6 到 Google Apps 脚本的 CORS 问题【英文标题】:CORS issue using GET from Angular 6 to Google Apps Script 【发布时间】:2019-02-16 08:00:15 【问题描述】:

我使用 Google Apps 脚本创建了一个非常简单的脚本,它读取电子表格并返回 JSON:

function doGet(e)

 // Change Spread Sheet url
 var ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1DLVP96405P7djwPAJpGRRgIOFCiJwnktr1Z4HFz9ooI/edit#gid=811553549");

// Sheet Name, Chnage Sheet1 to Users in Spread Sheet. Or any other name as you wish
 var sheet = ss.getSheetByName("NumeroMortosConfrontos");

 return getConfrontos(sheet); 



function getConfrontos(sheet)
  var jo = ;
  var dataArray = [];

// collecting data from 2nd Row , 1st column to last row and last column
  var rowCabecalho = sheet.getRange(18,1, 1, 6).getValues();
  var dataRowCabecalho = rowCabecalho[0];
  var cabecalho = [];
  cabecalho.push(dataRowCabecalho[0]);
  cabecalho.push(dataRowCabecalho[1]);
  cabecalho.push(dataRowCabecalho[2]);
  cabecalho.push(dataRowCabecalho[3]);
  cabecalho.push(dataRowCabecalho[4]);
  cabecalho.push(dataRowCabecalho[5]);  

  var rows = sheet.getRange(19,1, 14, 6).getValues();

  for(var i = 0, l= rows.length; i<l ; i++)
    var dataRow = rows[i];
    var record = [];
    record.push(dataRow[0]);
    record.push(dataRow[1]);
    record.push(dataRow[2]);
    record.push(dataRow[3]);
    record.push(dataRow[4]);
    record.push(dataRow[5]);

    dataArray.push(record);   
    

  jo.cabecalho = cabecalho;
  jo.dados = dataArray;

  var result = JSON.stringify(jo);

  return ContentService.createTextOutput(result).setMimeType(ContentService.MimeType.JSON);

  

发布后,我在浏览器中调用端点并且运行良好,如下链接所示:

https://script.google.com/macros/s/AKfycbxk616n8wjgGeHZIc3Hm66Kcv4ZtWKZJQnEKLsxZC9LpoDK8mQZ/exec

我尝试使用来自 Angular 应用程序的 HTTP Get 调用此链接,但是当我打开它时,我看到了错误:

加载资源失败:服务器响应状态为 405 () :4200/#/estatistica/confrontos:1 加载失败 https://script.google.com/macros/s/AKfycbxk616n8wjgGeHZIc3Hm66Kcv4ZtWKZJQnEKLsxZC9LpoDK8mQZ/exec: 对预检请求的响应未通过访问控制检查:否 请求中存在“Access-Control-Allow-Origin”标头 资源。因此不允许使用原点“http://localhost:4200” 访问。

我一直在搜索很多关于它的问题和答案,但我真的不知道我必须做什么,我需要编写什么配置以及在哪里(服务器端或客户端)。我该如何解决这个问题并在我的前端应用程序中接收 JSON?

【问题讨论】:

对于我的应用程序,我们已经按照(***.com/questions/3102819/…)中的答案处理了 4200 也访问其他主机的 cors 问题。 这个文档可能对developers.google.com/api-client-library/javascript/features/…有帮助 现在我收到另一个错误:无法加载 script.google.com/macros/s/…:预检响应没有 HTTP ok 状态。 尝试在这个答案中重置标题客户端:code-examples.net/en/q/2019f28 【参考方案1】:

我的 Angular 应用程序有一个拦截器类,它拦截所有 HTTP 请求并插入 JWT,然后将其发送到我的后端服务器(Spring Security)。

但是,我正在执行的这个 GET 请求不是针对我的后端,而是针对外部 Web 服务。当我在 GET 请求中将此 JWT 发送到 google 端点时,他们抱怨并且发生了这个 CORS 问题。

我想出了两个解决方案:

1) 不要直接从我的 Angular 应用程序发出这个 GET 请求,而是从我的后端应用程序处理数据,然后发送到 Angular 应用程序。

2) 防止特定的 HTTP 调用通过我的拦截器。这是我以前更快的解决方案,使用 HttpBackend,因此请求不会通过拦截器:

 private http: HttpClient;

  constructor(handler: HttpBackend) 
    this.http = new HttpClient(handler);
   

  linkTabela = 'https://script.google.com/macros/s/AKfycbxk616n8wjgGeHZIc3Hm66Kcv4ZtWKZJQnEKLsxZC9LpoDK8mQZ/exec';

    getTabela() 
      return this.http.get<TabelaEstatistica>(this.linkTabela);
    

【讨论】:

以上是关于使用 GET 从 Angular 6 到 Google Apps 脚本的 CORS 问题的主要内容,如果未能解决你的问题,请参考以下文章

使用使用 Angular 6 的服务将 JSON 文件从一个组件传递到另一个组件

在 Angular 6 中将 CORS 标头添加到响应中

Angular 从 1.6.6 升级到 6 时出现 $Injector 错误

Angular 6 - 从 observable 获取数据我做错了啥?

从 Angular 前端到 json-server 的 GET 调用访问被 CORS 策略阻止的 XMLHttpRequest

带有 HTTP 基本身份验证的 Angular 6 HTTP Get 请求