首页 > 解决方案 > 对 Google 表格发布页面的 XMLHTTPRequest 不起作用

问题描述

我希望将数据从多个 Google 表格传输到 Webflow 上的网站。表格中的数据会随着时间的推移而更新(有些是自动的,有些是手动的),我们的网站需要随之动态更新。直到几周前,我们才开始进行这项工作。我们使用了 Sheets 的“发布到 Web”功能,然后通过 xmlhttp 请求简单地从该页面中抓取。

然后,谷歌改变了他们的系统。我们使用的旧链接已被替换为以下页面:

Sheets v3 API 已被拒绝。如需更多信息,请访问:https ://cloud.google.com/blog/products/g-suite/migrate-your-apps-use-latest-sheets-api

使用 v4,您仍然可以发布到 Web,但它会输出不同的链接,当我们尝试使用 xmlhttp 调用请求它时,这会导致 CORS 问题。我们不断收到此错误:

从源“null”访问“https://docs.google.com/spreadsheets/u/2/d/e/2PACX-1vTkGAWMFigGt-_40bYYtR9OuDh5t0gO0B5tAUhiUg2-XuSXfIazjgbvoqBxvQxxIPr62OfmdWQaWtPt/pubhtml”的 XMLHttpRequest 已被 CORS 政策阻止:对预检的响应请求未通过访问控制检查:预检请求不允许重定向。

我不知道该怎么做,但在研究过程中,我发现谷歌似乎不希望人们首先从这个发布页面获取信息——它是一个链接发送给人们。

我们目前不确定该怎么做,可以使用一些帮助。是否有我们不知道的解决方法,或者我们可以完全使用不同的系统?

编码:

let fonds_xmlhttp = new XMLHttpRequest();
        fonds_xmlhttp.onload = function () {
            if (this.readyState == 4 && this.status == 200){
                let fonds_data = JSON.parse(this.responseText);
                // do stuff with fonds_data
            } else {
                console.log("status: " + this.status);
            }
        };
fonds_xmlhttp.open("GET", 
                   "https://docs.google.com/spreadsheets/u/2/d/e/2PACX-1vTkGAWMFigGt-_40bYYtR9OuDh5t0gO0B5tAUhiUg2-XuSXfIazjgbvoqBxvQxxIPr62OfmdWQaWtPt/pubhtml", 
                   true);

编辑:

这是我现在使用的流程......我只是想在 chrome 中打开这个 html 页面,现在使用@Tanaike 提供的脚本:

<meta name="viewport" content="width=device-width, initial-scale=1">

<body> 
    <div>
        <table class="fonds-tabelle">
            <thead>
                <tr>
                    <th> </th>
                    <th>2021</th>
                    <th>2020</th>
                    <th>2019</th>
                    <th>2018</th>
                    <th>2017</th>
                    <th>2016</th>
                    <th>Ø 3J</th>
                    <th>Ø 5J</th>
                </tr>
            </thead>
            <tbody id="fonds-daten"> 
            </tbody>
        </table>   
    </div> 
</body>

<script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.1.0/papaparse.min.js"></script>
<script type="text/javascript">
    let fonds_xmlhttp = new XMLHttpRequest();
    fonds_xmlhttp.onload = function () {
      if (this.readyState == 4 && this.status == 200){
        let [header, ...values] = Papa.parse(this.responseText).data;
        values = values.map(r => r.map(c => {
          const t = c.trim();
          return isNaN(t) ? t : Number(t);
        }));
        const fonds_data = values.map(r => r.reduce((o, c, j) => Object.assign(o, {[header[j] && header[j].trim()]: c}), {}));
        console.log(fonds_data);

        /* Then iterate over fonds_data and fill the tbody fonds-daten with it */
      } else {
        console.log("status: " + this.status);
      }
    };
    const url = "https://docs.google.com/spreadsheets/u/2/d/e/2PACX-1vTkGAWMFigGt-_40bYYtR9OuDh5t0gO0B5tAUhiUg2-XuSXfIazjgbvoqBxvQxxIPr62OfmdWQaWtPt/pub?output=csv";
    fonds_xmlhttp.open("GET", url, true);
    fonds_xmlhttp.send();

</script>

当我在 Chrome 中打开它时,我仍然收到以下 CORS 错误:

CORS 策略已阻止从源“null”访问“https://docs.google.com/spreadsheets/u/2/d/e/2PACX-1vTkGAWMFigGt-_40bYYtR9OuDh5t0gO0B5tAUhiUg2-XuSXfIazjgbvoqBxvQxxIPr62OfmdWQaWtPt/pub?output=csv”的 XMLHttpRequest :请求的资源上不存在“Access-Control-Allow-Origin”标头。

标签: javascriptgoogle-sheetsxmlhttprequestwebflow

解决方案


问题和解决方法:

我认为您的问题的原因可能是由于https://docs.google.com/spreadsheets/u/2/d/e/2PACX-1vTkGAWMFigGt-_40bYYtR9OuDh5t0gO0B5tAUhiUg2-XuSXfIazjgbvoqBxvQxxIPr62OfmdWQaWtPt/pubhtml.

在您的情况下,作为一种解决方法,如何将您的端点修改为https://docs.google.com/spreadsheets/u/2/d/e/2PACX-1vTkGAWMFigGt-_40bYYtR9OuDh5t0gO0B5tAUhiUg2-XuSXfIazjgbvoqBxvQxxIPr62OfmdWQaWtPt/pub?output=csv?这样,可以将数据检索为 CSV 数据。因此,在解析检索到的 CSV 数据时,可以将其转换为二维数组和 JSON 对象。

示例修改脚本如下。

修改后的脚本:

在此修改中,为了解析 CSV 数据,https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.1.0/papaparse.min.js使用了库。

let fonds_xmlhttp = new XMLHttpRequest();
fonds_xmlhttp.onload = function () {
  if (this.readyState == 4 && this.status == 200){
    let [header, ...values] = Papa.parse(this.responseText).data;
    values = values.map(r => r.map(c => {
      const t = c.trim();
      return isNaN(t) ? t : Number(t);
    }));
    const fonds_data = values.map(r => r.reduce((o, c, j) => Object.assign(o, {[header[j] && header[j].trim()]: c}), {}));
    console.log(fonds_data)
  } else {
    console.log("status: " + this.status);
  }
};
const url = "https://docs.google.com/spreadsheets/u/2/d/e/2PACX-1vTkGAWMFigGt-_40bYYtR9OuDh5t0gO0B5tAUhiUg2-XuSXfIazjgbvoqBxvQxxIPr62OfmdWQaWtPt/pub?output=csv";
fonds_xmlhttp.open("GET", url, true);
fonds_xmlhttp.send();
  • 在此修改后的脚本中,请添加<script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.1.0/papaparse.min.js"></script>. 如果您可以通过自己的脚本解析 CSV 数据,则无需使用此库即可实现目标。

  • 运行此修改后的脚本时,将获得以下结果。

      [
        {"2016":"5,01%","2017":"6,20%","2018":"-5,06%","2019":"20,42%","2020":"3,98%","2021":"5,95%","":"Flossbach von Storch","D3J":"9,54%","D5J":"7,20%"},
        {"2016":"6,62%","2017":"6,81%","2018":"-3,42%","2019":"19,31%","2020":"13,32%","2021":"5,57%","":"Phaidros Balanced D","D3J":"10,88%","D5J":"9,82%"},
        {"2016":"-0,38%","2017":"10,09%","2018":"-11,14%","2019":"25,38%","2020":"13,99%","2021":"16,59%","":"ODDO BHF","D3J":"13,72%","D5J":"10,93%"},
        {"2016":"2,53%","2017":"8,88%","2018":"-0,42%","2019":"18,33%","2020":"7,08%","2021":"9,32%","":"Acatis Gané Value","D3J":"10,72%","D5J":"10,16%"},
        {"2016":"2,66%","2017":"12,81%","2018":"0,99%","2019":"27,33%","2020":"-1,40%","2021":"10,59%","":"Capital Growth","D3J":"12,18%","D5J":"11,80%"}
      ]
    
  • 如果您想以二维数组的形式检索数据,您可以从Papa.parse(this.responseText).data.

参考:


推荐阅读