首页 > 解决方案 > 从谷歌地图读取kml文件时如何避免CORS错误

问题描述

我想从 url 读取 kml 文件https://www.google.com/maps/d/u/0/kml?mid=1CUrmiiSysq2amCr5_6-YcOcg36sf3CpU&forcekml=1

当我在浏览器中输入这个 url 时,我可以下载它,但是在尝试读取 php(服务器端)或 js 脚本(客户端)时出现 CORS 错误:

Access to XMLHttpRequest at 'https://www.google.com/maps/d/u/0/kml?mid=1CUrmiiSysq2amCr5_6-YcOcg36sf3CpU&forcekml=1' 
from origin 'https://my-app-domain.pl' 
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

我正在使用的脚本

var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        // reading and parsing code will go here
    }
};
xhttp.open("POST", "https://www.google.com/maps/d/u/0/kml?mid=1CUrmiiSysq2amCr5_6-YcOcg36sf3CpU&forcekml=1", true);
xhttp.send();

我想自动读取此文件以在 csv 文件中提取和保存一些数据。

我尝试使用 Abronsius 教授在下面解释的服务器端(php 脚本)读取 kml 文件,file_get_contents( "https://www.google.com/maps/d/u/0/kml?mid=1CUrmiiSysq2amCr5_6-YcOcg36sf3CpU&forcekml=1" ) 如果地图的访问不受限制,它就可以工作。

当我将地图设为私有时,出现错误:failed to open stream: HTTP request failed! HTTP/1.0 403 Forbidden

因此,在服务器端访问被禁止,在客户端存在 CORS 错误。

这个问题有什么解决办法吗?

标签: google-mapscorskml

解决方案


我发现这个特定的端点不需要 cURL 来下载 - 一个简单file_get_contents的就足够了,所以 PHP 代理脚本可以非常简单。如果您使用会话变量,您只需将请求发送给 Google 一次 - 后续请求可以由会话变量提供服务。

例如:

<?php
    session_start();
    
    if( $_SERVER['REQUEST_METHOD']=='POST' && isset( $_POST['task'] ) && $_POST['task']=='download-kml' ){
        if( !isset( $_SESSION['kml-file'] ) ){
            $_SESSION['kml-file']=file_get_contents( 'https://www.google.com/maps/d/u/0/kml?mid=1CUrmiiSysq2amCr5_6-YcOcg36sf3CpU&forcekml=1' );
        }
        ob_clean();
        header('Content-Type: application/xml');
        exit( $_SESSION['kml-file'] );
    }
?>
<!DOCTYPE html>
<html lang='en'>
    <head>
        <meta charset='utf-8' />
        <title>Google Maps - KML cors issue bypass proxy</title>
    </head>
    <body>
        <script>
            let fd=new FormData();
                fd.set('task','download-kml');

            fetch( location.href, { method:'post', body:fd } )
                .then( r=>{ return r.text() })
                .then( data=>{
                    /* process the XML as you need */
                    console.info( data );
                })
        </script>
    </body>
</html>

推荐阅读