js实现下载shp文件

发布时间 2023-08-14 12:44:06作者: 雨崩

AP!

浏览器是不会默认支持shp的相关文件的下载,仅有里面的.shp.xml是支持的,其他的如

var shpArr = [".cpg", ".dbf", ".prj", ".sbn", ".sbx", ".shp",".shp.xml", ".shx",];

因而需要确保服务器上的配置允许浏览器支持 .shp 文件的下载

 

MIME 类型设置: 您需要在服务器上配置正确的 MIME 类型,以便浏览器能够正确识别 .shp 文件并进行下载。.shp 文件是一种地理信息系统(GIS)数据文件,通常使用的 MIME 类型是 application/octet-stream。您可以通过服务器配置或者 .htaccess 文件来添加该 MIME 类型。

 

我的配置

Visual Studio 2017 + IIS Express 

使用该服务器只需要在Web.config中添加支持的类型进行配置。

具体如下:

<configuration>

    <system.web>
        <compilation debug="true" targetFramework="4.0" />
     <!--最大请求长度,单位为KB(千字节),默认为4M,设置为1G,上限为2G   287B9DF08F4F79FDF28EE7765C645325-->
    <httpRuntime maxRequestLength="1048576" executionTimeout="3600" />
    </system.web>

<system.webServer>
    <staticContent>
        <mimeMap fileExtension=".shp" mimeType="application/octet-stream" />
      <mimeMap fileExtension=".cpg" mimeType="application/octet-stream" />
      <mimeMap fileExtension=".dbf" mimeType="application/octet-stream" />
    <mimeMap fileExtension=".prj" mimeType="application/octet-stream" />
    <mimeMap fileExtension=".sbn" mimeType="application/octet-stream" />
  <mimeMap fileExtension=".sbx" mimeType="application/octet-stream" />
  <mimeMap fileExtension=".shp.xml" mimeType="application/octet-stream" />
  <mimeMap fileExtension=".shx" mimeType="application/octet-stream" />
        <!-- 添加其他文件类型的 MIME 类型   -->
    </staticContent>

 <!-- 若要确保浏览器下载文件而不是在浏览器中打开
          <httpProtocol>
        <customHeaders>
            <add name="Content-Disposition" value="attachment" />
        </customHeaders>
    </httpProtocol>    
    -->

  <appSettings>
       <!-- 添加key  -->
  </appSettings>
</system.webServer>

</configuration>

配置完成后先保存,然后关掉整个VS,最后打开后点击解决方案重新生成即可!

然后点击html调试,发现所有shp相关文件都可以下载了!!!

 

js下载的方法比较:

1、forEach()
 var shpArr = [".cpg", ".dbf", ".prj", ".sbn", ".sbx", ".shp",".shp.xml", ".shx",];

    shpArr.forEach(function (extension) {
                            var fileNoextName = fileName.split('.')[0];
                            var relatedFileName = fileNoextName + extension;
                            let relatedA = document.createElement('a');
                            relatedA.download = relatedFileName;
                            relatedA.style.display = 'none';
                            var relatePath = "./uploadfiles/" + relatedFileName;
                            console.log('@relatePath', relatePath)
                            relatedA.href = relatePath; 
                            document.body.appendChild(relatedA);
                            relatedA.click();
                            document.body.removeChild(relatedA);
                        });

 

当在 forEach 循环中进行异步操作时,循环会继续进行并迅速完成所有迭代,而不会等待异步操作的完成。这可能会导致在同一时间内,所有异步操作都在短时间内开始,但由于异步操作需要一些时间来完成,只有最后一个或者某个随机操作会真正完成。其他的操作可能会被中断或被忽略,因为在它们开始执行后,循环已经完成。

这就是为什么在你的代码中,下载操作只执行一次的原因。循环迅速地开始了每个下载操作,但在下载完成之前循环已经结束,导致只有最后一个下载操作真正完成。

为了解决这个问题,你需要使用异步控制机制,比如 async/await,或者使用 Promise,来确保在一个异步操作完成之后再继续执行下一个。这样可以避免循环中的异步操作与循环本身的不同步问题。

 

2、async/await

                        async function downloadRelatedFiles() {
                            for (const extension of shpArr) {
                                var fileNoextName = fileName.split('.')[0];
                                var relatedFileName = fileNoextName + extension;
                                let relatedA = document.createElement('a');
                                relatedA.download = relatedFileName;
                                relatedA.style.display = 'none';
                                var relatePath = "./uploadfiles/" + relatedFileName + "?timestamp=" + Date.now();
                                console.log('@relatePath', relatePath);
                                relatedA.href = relatePath;
                                document.body.appendChild(relatedA);
                                relatedA.click();
                                document.body.removeChild(relatedA);
                                // Wait for a short period before the next iteration to ensure downloads are complete
                                await new Promise(resolve => setTimeout(resolve, 500));
                            }
                        }
                        downloadRelatedFiles();

 

3、Promise

test时该方法成功下载!

                        function downloadRelatedFile(extension) {
                            return new Promise((resolve, reject) => {
                                var fileNoextName = fileName.split('.')[0];
                                var relatedFileName = fileNoextName + extension;
                                let relatedA = document.createElement('a');
                                relatedA.download = relatedFileName;
                                relatedA.style.display = 'none';
                                var relatePath = "./uploadfiles/" + relatedFileName;
                                console.log('@relatePath', relatePath)
                                relatedA.href = relatePath;
                                document.body.appendChild(relatedA);

                                relatedA.addEventListener('click', () => {
                                    document.body.removeChild(relatedA);
                                    resolve(); // Resolve the promise when the download is complete
                                });
                                relatedA.click();
                            });
                        }

                        async function downloadAllRelatedFiles() {
                            try {
                                const promises = shpArr.map(extension => downloadRelatedFile(extension));
                                await Promise.all(promises);
                                console.log('All files downloaded successfully');
                            } catch (error) {
                                console.error('Error downloading files:', error);
                            }
                        }

                        downloadAllRelatedFiles();