fix mercury parser encoding detection

This commit is contained in:
刘浩远 2020-08-09 18:22:01 +08:00
parent 7deb250bcc
commit 42e819834b
2 changed files with 13 additions and 7 deletions

View File

@ -5,7 +5,7 @@ import { RSSItem } from "../scripts/models/item"
import { Stack, CommandBarButton, IContextualMenuProps, FocusZone, ContextualMenuItemType, Spinner, Icon, Link } from "@fluentui/react"
import { RSSSource, SourceOpenTarget } from "../scripts/models/source"
import { shareSubmenu } from "./context-menu"
import { platformCtrl } from "../scripts/utils"
import { platformCtrl, decodeFetchResponse } from "../scripts/utils"
const FONT_SIZE_OPTIONS = [12, 13, 14, 15, 16, 17, 18, 19, 20]
@ -214,7 +214,9 @@ class Article extends React.Component<ArticleProps, ArticleState> {
loadFull = async () => {
this.setState({ fullContent: "", loaded: false, error: false })
try {
const html = await (await fetch(this.props.item.link)).text()
const result = await fetch(this.props.item.link)
if (!result || !result.ok) throw new Error()
const html = await decodeFetchResponse(result)
this.setState({ fullContent: html })
} catch {
this.setState({ loaded: true, error: true, errorDescription: "MERCURY_PARSER_FAILURE" })

View File

@ -29,6 +29,14 @@ const rssParser = new Parser({
})
const CHARSET_RE = /charset=([^()<>@,;:\"/[\]?.=\s]*)/i
export async function decodeFetchResponse(response: Response) {
const buffer = await response.arrayBuffer()
const ctype = response.headers.has("content-type") && response.headers.get("content-type")
const charset = (ctype && CHARSET_RE.test(ctype)) ? CHARSET_RE.exec(ctype)[1] : "utf-8"
const decoder = new TextDecoder(charset)
return decoder.decode(buffer)
}
export async function parseRSS(url: string) {
let result: Response
try {
@ -38,11 +46,7 @@ export async function parseRSS(url: string) {
}
if (result && result.ok) {
try {
const buffer = await result.arrayBuffer()
const ctype = result.headers.has("content-type") && result.headers.get("content-type")
const charset = (ctype && CHARSET_RE.test(ctype)) ? CHARSET_RE.exec(ctype)[1] : "utf-8"
const decoder = new TextDecoder(charset)
return await rssParser.parseString(decoder.decode(buffer))
return await rssParser.parseString(await decodeFetchResponse(result))
} catch {
throw new Error(intl.get("log.parseError"))
}