【问题标题】:XMLHTTPRequest to Google Sheets Published Page Not Working对 Google 表格发布页面的 XMLHTTPRequest 不起作用
【发布时间】:2021-11-28 14:39:13
【问题描述】:

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

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

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

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

访问 XMLHttpRequest 在 'https://docs.google.com/spreadsheets/u/2/d/e/2PACX-1vTkGAWMFigGt-_40bYYtR9OuDh5t0gO0B5tAUhiUg2-XuSXfIazjgbvoqBxvQxxIPr62OfmdWQaWtPt/pubhtml' CORS 策略已阻止来自原点“null”:响应 预检请求未通过访问控制检查:重定向未通过 允许预检请求。

我不知道该怎么做,但在研究过程中,我发现 Google 似乎一开始就不希望人们从这个发布页面获取信息——它的本意是发送给他人的链接。

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

代码:

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 错误:

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

【问题讨论】:

    标签: javascript google-sheets xmlhttprequest webflow


    【解决方案1】:

    问题和解决方法:

    我认为您的问题的原因可能是由于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();
    
    • 在此修改后的脚本中,请添加&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.1.0/papaparse.min.js"&gt;&lt;/script&gt;。如果您可以通过自己的脚本解析 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检索。

    参考:

    【讨论】:

    • 感谢您的详细解答!不幸的是,我仍然收到此 CORS 错误...“从源 'null' 访问 XMLHttpRequest 在 'docs.google.com/spreadsheets/u/2/d/e/…' 已被 CORS 策略阻止:没有 'Access-Control-Allow-Origin' 标头存在于请求的资源。”
    • @candybowl 感谢您的回复。我为此道歉。不幸的是,我无法复制您的情况。当我测试我提出的脚本时,没有发生错误。对于这种情况,我深表歉意。那么您能否提供正确复制问题的详细流程?通过这个,我想尝试复制它。
    • 最终,我将通过 html 中的 WebFlow 运行这一切。但现在,我只是想在 Chrome 上运行一个 html 文件。 StackOverflow 不允许我在评论中发布整个文件,但我只是将您的脚本复制到
    • @candybowl 感谢您的回复。我不得不再次为我糟糕的英语水平道歉。不幸的是,从您的回复中,我无法理解正确复制您的问题的流程。因此,为了正确理解您当前的问题,您能否提供正确复制问题的详细流程?通过这个,我想尝试复制它。
    • 感谢您的帮助!我编辑了原始帖子以解释流程。评论部分不允许足够的字符。所以请再看一遍帖子,你会看到一个“编辑”部分,我在 html 文件中尝试你的脚本。再次感谢您!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-12
    • 1970-01-01
    • 1970-01-01
    • 2021-07-01
    • 2017-06-03
    • 2014-12-13
    相关资源
    最近更新 更多