获取public文件

vue

Posted by Shallow Dreamer on April 22, 2023

在Vue中获取public文件夹路径可以使用相对路径,也可以使用绝对路径。相对路径可以使用process.env.BASE_URL变量,它会被Webpack解析为Vue应用的根路径。绝对路径可以使用process.env.PUBLIC_URL变量,它是public文件夹的绝对路径。

以下是一个示例代码,演示如何在Vue中获取public文件夹路径并在Python中遍历:

Vue代码:

<template>
  <div>
    <button @click="getPublicPath">获取public文件夹路径</button>
  </div>
</template>

<script>
export default {
  methods: {
    getPublicPath() {
      const publicPath = process.env.BASE_URL || process.env.PUBLIC_URL
      console.log(publicPath) // 打印public文件夹路径
      // 将public文件夹路径发送到后端进行处理
      // axios.post('/handle_public_path', { publicPath })
    }
  }
}
</script>

Python代码:

import os

from flask import Flask, request

app = Flask(__name__)

@app.route('/handle_public_path', methods=['POST'])
def handle_public_path():
    public_path = request.json['publicPath']
    public_path = os.path.abspath(public_path)
    
    for root, dirs, files in os.walk(public_path):
        # root为当前目录的绝对路径,dirs为当前目录下的子目录名,files为当前目录下的文件名
        for file in files:
            # 处理文件
            print(os.path.join(root, file))
        for dir in dirs:
            # 处理目录
            print(os.path.join(root, dir))
    
    return 'OK'

在这个示例代码中,我们在Vue中定义了一个getPublicPath()方法,它获取public文件夹的路径并使用axios将路径发送到后端。后端使用Flask框架接收POST请求,并从请求的JSON数据中获取public文件夹路径。然后,我们使用os.path.abspath()函数将路径转换为绝对路径,并使用os.walk()函数遍历public文件夹中的所有文件和文件夹。

如果Vue项目和Python项目不在同一文件夹下,那么可以考虑使用相对路径来获取公共文件夹(public folder)的绝对路径。在Vue项目中,可以使用process.env.PUBLIC_URL来获取public文件夹的相对路径,然后在Python项目中使用os.path.join()函数将相对路径转化为绝对路径。具体实现步骤如下:

1.在Vue项目中,在组件中使用process.env.PUBLIC_URL来获取public文件夹的相对路径,如下所示:

<script>
export default {
  mounted() {
    const publicPath = process.env.PUBLIC_URL;
    console.log(publicPath);
    // do something with publicPath, such as pass it to the backend
  },
};
</script>

2.将获取到的相对路径传递给后端的Python项目。在Python项目中,可以使用os.path.join()函数将相对路径转化为绝对路径,如下所示:

import os

# assume publicPath is the relative path of the public folder received from frontend
publicPath = "/my/vue/project/public"
# get the absolute path of the public folder
absPath = os.path.join(os.getcwd(), publicPath)
# list all directories and files under the public folder
for root, dirs, files in os.walk(absPath):
    for file in files:
        print(os.path.join(root, file))

这里使用了os.path.join()函数将当前工作目录和public文件夹的相对路径连接起来得到public文件夹的绝对路径,并使用os.walk()函数遍历public文件夹下的所有文件和文件夹。

如果Vue项目和Python项目不在同一文件夹中,那么可以使用相对路径或绝对路径来访问public文件夹。以下是一种可能的解决方案:

  1. 在Vue项目中,使用Node.js的path模块获取public文件夹的绝对路径,并将其保存到一个常量中。例如,在Vue组件中:
const publicPath = path.resolve(__dirname, '../public');

其中,__dirname表示当前组件所在的目录。

  1. 将上述常量通过HTTP请求或其他方式发送给Python后端,Python后端可以读取这个值,并使用它来访问Vue项目中的public文件夹。

例如,在Python中使用os模块来访问public文件夹:

import os

public_path = '/path/to/vue/project/public'
files = os.listdir(public_path)

其中,/path/to/vue/project/public为Vue项目中public文件夹的绝对路径,可以在Python中替换为上一步中传递的值。

需要注意的是,为了保证跨平台的兼容性,建议在Vue项目中使用path.resolve()方法获取路径,而在Python项目中使用os.path.join()方法来拼接路径。

当publicPath为’/’时,可以使用以下代码来获取Vue中public文件夹的绝对路径:

const path = require('path');
const absolutePath = path.join(__dirname, 'public');

其中,__dirname是Node.js中的一个全局变量,表示当前文件所在的目录的绝对路径。

在Python中,可以使用os模块来访问这个文件夹。例如:

import os

public_path = '/path/to/public/folder'
files = os.listdir(public_path)

这里的public_path需要替换成上述代码中获取到的绝对路径。os.listdir()方法可以列出指定路径下的所有文件和文件夹。

如果vue项目和python项目不在同一个地方,并且publicPath为’/’,那么可以考虑在Vue项目中使用相对路径来获取public文件夹的绝对路径,并将该路径传递给后端的Python程序。具体步骤如下:

  1. 在Vue项目中创建一个用于获取public文件夹绝对路径的函数,如下所示:
function getPublicFolderPath() {
  const currentUrl = window.location.href;
  const currentPath = currentUrl.substr(0, currentUrl.lastIndexOf('/'));
  const publicPath = currentPath + '/public';
  return publicPath;
}
  1. 在Vue项目中调用该函数,并将返回的路径作为参数传递给后端Python程序,如下所示:
// 在Vue项目中调用getPublicFolderPath函数,并将返回的路径传递给后端Python程序
const publicPath = getPublicFolderPath();
axios.post('/api/get_folder_content', { publicPath }).then(response => {
  console.log(response.data);
});
  1. 在后端的Python程序中,使用传递过来的路径来遍历public文件夹中的内容,如下所示:
import os

def get_folder_content(request):
    public_path = request.POST.get('publicPath')
    file_list = []
    for root, dirs, files in os.walk(public_path):
        for file in files:
            file_path = os.path.join(root, file)
            file_list.append(file_path)
    return JsonResponse({'file_list': file_list})

这样,在Vue项目中通过相对路径获取public文件夹的绝对路径,再将该路径传递给后端的Python程序,就可以在Python程序中遍历public文件夹中的内容了。

如果在Vue项目中无法设置绝对路径变量,可以考虑使用相对路径获取public文件夹的绝对路径,然后在Python中使用绝对路径访问文件夹。

在Vue中,可以使用以下方法获取public文件夹的相对路径:

const path = require('path')
const publicPath = process.env.BASE_URL
const absolutePath = path.resolve(__dirname, publicPath)

其中,process.env.BASE_URL是通过vue.config.js中的publicPath配置获取的。__dirname代表当前文件的绝对路径,path.resolve将相对路径解析为绝对路径。

然后,可以将absolutePath作为参数传递给Python脚本,在Python中使用绝对路径访问public文件夹。例如:

import os

public_folder_path = '/path/to/public/folder'
file_list = os.listdir(public_folder_path)

这里的public_folder_path应该替换成上面获取到的absolutePathos.listdir可以获取文件夹中的文件列表。

如果vue项目和python项目不在同一个地方,并且publicPath为’/’时,可以通过以下步骤获取vue中public的绝对路径,并在python访问其中的文件夹:

  1. 在Vue项目中,使用process.env.BASE_URL获取当前应用的基本URL。

  2. 在Vue项目中,通过创建一个全局变量来存储公共文件夹的路径,并将其赋值为process.env.BASE_URL + 'public/'。例如:

    // 在main.js中创建全局变量
    Vue.prototype.$publicPath = process.env.BASE_URL + 'public/'
    
  3. 在Python项目中,使用Python的os模块来获取Vue项目中public文件夹的绝对路径。首先,需要确定Vue项目的根目录,然后使用该路径来获取public文件夹的绝对路径。例如:

    import os
       
    # 获取Vue项目根目录的绝对路径
    root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../vue_project'))
       
    # 获取public文件夹的绝对路径
    public_path = os.path.join(root_path, 'public')
    

    这里的__file__表示当前Python文件的路径,../vue_project表示Vue项目所在的目录相对于Python项目的相对路径。

    请注意,如果Vue项目和Python项目在不同的机器上,则需要相应地更改Vue项目根目录的绝对路径。

如果Vue项目和Python项目不在同一个地方,并且publicPath'/',则可以通过以下方式获取Vue中public文件夹的绝对路径:

const path = require('path')

// 获取当前文件所在的绝对路径
const currentPath = path.resolve(__dirname)

// 获取public文件夹所在的绝对路径
const publicPath = path.join(currentPath, '../public')

这里使用了path模块来获取绝对路径。首先,使用path.resolve(__dirname)获取当前文件所在的绝对路径;然后,使用path.join(currentPath, '../public')获取public文件夹所在的绝对路径。

在Python中访问其中的文件夹,则可以使用Python的os模块来实现。假设Vue中public文件夹所在的绝对路径为/path/to/public,可以在Python中使用以下代码来访问其中的文件夹:

import os

public_path = '/path/to/public'

# 遍历public文件夹中的所有文件和文件夹
for dirpath, dirnames, filenames in os.walk(public_path):
    for dirname in dirnames:
        print(os.path.join(dirpath, dirname))
    for filename in filenames:
        print(os.path.join(dirpath, filename))

在浏览器端获取Vue项目中的public文件夹绝对路径是不太可行的,因为浏览器不允许直接访问文件系统,浏览器只能通过HTTP协议向服务器请求文件。因此,如果需要访问public文件夹中的文件,建议将这些文件上传到服务器端,然后再通过HTTP协议从服务器端获取文件。如果仅仅需要获取public文件夹的绝对路径,可以在Vue项目中定义一个全局变量来保存public文件夹的路径,然后在Vue组件中通过访问这个全局变量来获取public文件夹的路径。例如,在Vue项目的入口文件中(通常是main.js文件)可以定义一个全局变量:

// main.js
Vue.prototype.$publicPath = process.env.BASE_URL + 'public/';

然后,在Vue组件中就可以通过访问this.$publicPath来获取public文件夹的路径了。请注意,process.env.BASE_URL是Vue项目的根路径,需要根据实际情况来修改。

要在Vue中读取public中的文件夹中的txt文件内容,可以使用axios库发起HTTP请求,然后将响应数据以字符串形式读取出来。

首先需要确保txt文件已经被部署到public文件夹中。然后,可以在Vue组件的methods属性中定义一个方法来读取txt文件的内容,如下所示:

import axios from 'axios';

export default {
  methods: {
    async readTxtFile() {
      try {
        const response = await axios.get('/txt-file.txt');
        const fileContent = response.data;
        // 处理txt文件内容
        console.log(fileContent);
      } catch (error) {
        console.error(error);
      }
    }
  }
};

在这个例子中,我们使用了axios库发起GET请求,请求路径为’/txt-file.txt’,这会让请求去访问public文件夹中的txt-file.txt文件。然后,我们读取响应数据的data属性,并将其保存在一个变量中。最后,我们可以对文件内容进行处理,比如将其显示在页面上或将其传递给其他函数。

需要注意的是,由于我们是在Vue组件中进行HTTP请求的,因此需要在Vue组件所在的域名下部署txt文件,否则会出现跨域请求的问题。如果txt文件被部署到了不同的域名下,需要在服务器端配置跨域请求的响应头。

import os
from django.http import JsonResponse, FileResponse
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def folder(request, folder_name):
    folder_path = os.path.join('public', folder_name)
    if not os.path.exists(folder_path):
        return JsonResponse({'error': 'Folder does not exist.'})
files = []
txt_content = ''
for file_name in os.listdir(folder_path):
    file_path = os.path.join(folder_path, file_name)
    if os.path.isfile(file_path):
        file_type = os.path.splitext(file_name)[1]
        is_txt = file_type == '.txt'
        is_pdf = file_type == '.pdf'
        files.append({
            'name': file_name,
            'link': f'/{folder_name}/{file_name}' if not is_txt else None,
            'isFolder': False,
            'isTxt': is_txt,
            'isPdf': is_pdf
        })
        if is_txt:
            with open(file_path, 'r') as f:
                txt_content += f.read()
    elif os.path.isdir(file_path):
        files.append({
            'name': file_name,
            'link': None,
            'isFolder': True
        })

return JsonResponse({'files': files, 'txtContent': txt_content})

对于这个需求,由于需要从服务器端获取文件夹内的内容并生成相应的链接,因此需要通过Vue的异步请求与后端进行通信。具体步骤如下:

  1. 在Vue组件中定义一个data属性,用于存储文件夹的内容列表,如下所示:
data() {
  return {
    folderContent: []
  }
}
  1. 在组件的created钩子函数中,通过Vue的异步请求从后端获取文件夹的内容列表,如下所示:
created() {
  axios.get('/api/folder/content').then(response => {
    this.folderContent = response.data;
  });
}
  1. 在组件的template中,通过v-for指令遍历文件夹的内容列表,并根据文件类型生成相应的链接或展示文件内容,如下所示:
<ul>
  <li v-for="item in folderContent" :key="item.name">
    <span v-if="item.type === 'directory'" class="folder-title"></span>
    <a v-else-if="item.type === 'pdf'" :href="item.path" target="_blank"></a>
    <span v-else-if="item.type === 'txt'" class="text-content"></span>
    <a v-else :href="item.path" download></a>
  </li>
</ul>
  1. 在后端使用Django框架,定义一个API接口,用于返回指定文件夹内的内容列表,并根据文件类型生成相应的数据,如下所示:
import os
from django.http import JsonResponse

def get_folder_content(request):
    folder_path = os.path.join(os.getcwd(), 'public')
    folder_content = []

    for item in os.listdir(folder_path):
        item_path = os.path.join(folder_path, item)

        if os.path.isdir(item_path):
            folder_content.append({
                'name': item,
                'type': 'directory'
            })
        elif os.path.isfile(item_path):
            if item.endswith('.pdf'):
                folder_content.append({
                    'name': item,
                    'path': f'/public/{item}',
                    'type': 'pdf'
                })
            elif item.endswith('.txt'):
                with open(item_path, 'r') as f:
                    content = f.read()
                folder_content.append({
                    'name': item,
                    'content': content,
                    'type': 'txt'
                })
            else:
                folder_content.append({
                    'name': item,
                    'path': f'/public/{item}',
                    'type': 'file'
                })

    return JsonResponse(folder_content, safe=False)

需要注意的是,需要在Django的settings.py文件中设置静态文件目录:

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'public'),
]

这样,前端就可以从服务器端获取文件夹的内容,并根据文件类型生成相应的链接或展示文件内容了。