Skip to content

Conversation

@JyiDeng
Copy link
Collaborator

@JyiDeng JyiDeng commented Oct 15, 2025

windows11,python3.10
用网页端运行脉经文件后,能够输出的文件名形如:脉经_simple_chinese_gbk_simple_chinese_output_2025-10-16_01-16-32.zip

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Fix garbled filenames in downloads by correctly setting and exposing Content-Disposition headers and parsing them on the frontend.

  • Backend: Set Content-Disposition using RFC 2231 (filename*) for non-ASCII names and expose the header via CORS.
  • Frontend: Robustly parse filename* and filename from Content-Disposition and decode percent-encoded UTF-8.

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.

File Description
rimetool/rimetool_gui/templates/new_index.html Parse RFC 2231 filename* and fallback filename from Content-Disposition; add logging and decoding.
rimetool/rimetool_gui/new_app.py Expose Content-Disposition via CORS; set Content-Disposition for ASCII and UTF-8 filenames; add logging and response headers.

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +302 to 303
encoded_filename = quote(original_filename)
response.headers["Content-Disposition"] = f"attachment; filename*=UTF-8''{encoded_filename}"
Copy link

Copilot AI Oct 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

quote is used but not imported, which will raise NameError at runtime. Import it (e.g., from urllib.parse import quote) at module level or use urllib.parse.quote. The same issue also occurs at line 365.

Copilot uses AI. Check for mistakes.
Comment on lines 365 to +366
encoded_filename = quote(safe_filename)
response.headers['Content-Disposition'] = (
f'attachment; filename="{ascii_filename}"; '
f"filename*=UTF-8''{encoded_filename}"
)
response.headers['Content-Disposition'] = f"attachment; filename*=UTF-8''{encoded_filename}"
Copy link

Copilot AI Oct 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

quote is referenced here as well without an import. Add from urllib.parse import quote at the top of the file or qualify it as urllib.parse.quote.

Copilot uses AI. Check for mistakes.
Comment on lines +363 to +367
# 包含中文,使用RFC 2231标准格式
# filename*=UTF-8''编码后的文件名
encoded_filename = quote(safe_filename)
response.headers['Content-Disposition'] = (
f'attachment; filename="{ascii_filename}"; '
f"filename*=UTF-8''{encoded_filename}"
)
response.headers['Content-Disposition'] = f"attachment; filename*=UTF-8''{encoded_filename}"
logger.info(f"设置UTF-8编码文件名: {encoded_filename}")
Copy link

Copilot AI Oct 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] For broader client compatibility, include both filename (ASCII fallback) and filename* (UTF-8) in Content-Disposition when the name contains non-ASCII characters. Example: response.headers['Content-Disposition'] = f'attachment; filename="{ascii_fallback}"; filename*=UTF-8''{encoded_filename}'. The previous version provided this dual format; restoring it avoids regressions on older or non-compliant clients.

Copilot uses AI. Check for mistakes.
# 启用 CORS,并暴露Content-Disposition头供前端JavaScript访问
# CORS(app, origins="http://localhost:5500") # 允许来自 http://localhost:5500 的请求
CORS(app, origins="*")
CORS(app, origins="*", expose_headers=["Content-Disposition"])
Copy link

Copilot AI Oct 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Access-Control-Expose-Headers is configured globally via Flask-CORS (line 72) and also set per response (lines 309 and 370). Keep one approach (prefer the global Flask-CORS config) to avoid duplication and drift.

Copilot uses AI. Check for mistakes.
response.headers["Content-Type"] = "application/octet-stream"
response.headers["X-Content-Type-Options"] = "nosniff"
# 确保前端JavaScript可以访问Content-Disposition头
response.headers["Access-Control-Expose-Headers"] = "Content-Disposition"
Copy link

Copilot AI Oct 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Access-Control-Expose-Headers is configured globally via Flask-CORS (line 72) and also set per response (lines 309 and 370). Keep one approach (prefer the global Flask-CORS config) to avoid duplication and drift.

Suggested change
response.headers["Access-Control-Expose-Headers"] = "Content-Disposition"

Copilot uses AI. Check for mistakes.
logger.info(f"设置UTF-8编码文件名: {encoded_filename}")

# 确保前端JavaScript可以访问Content-Disposition头
response.headers['Access-Control-Expose-Headers'] = 'Content-Disposition'
Copy link

Copilot AI Oct 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Access-Control-Expose-Headers is configured globally via Flask-CORS (line 72) and also set per response (lines 309 and 370). Keep one approach (prefer the global Flask-CORS config) to avoid duplication and drift.

Suggested change
response.headers['Access-Control-Expose-Headers'] = 'Content-Disposition'

Copilot uses AI. Check for mistakes.
@whitewatercn
Copy link
Collaborator

先merge了试试看,不行再改

@whitewatercn whitewatercn merged commit 27b45b4 into B-Beginner:master Oct 16, 2025
@whitewatercn whitewatercn mentioned this pull request Oct 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants