|
|
@@ -1,4 +1,4 @@
|
|
|
-import { ref, nextTick } from 'vue'
|
|
|
+import { ref, nextTick } from 'vue'
|
|
|
import { storeToRefs } from 'pinia'
|
|
|
import { parse, type Shape, type Element, type ChartItem, type BaseElement } from 'pptxtojson'
|
|
|
import { nanoid } from 'nanoid'
|
|
|
@@ -1934,7 +1934,7 @@ export default () => {
|
|
|
return new Promise((resolve, reject) => {
|
|
|
console.log('直接使用原始 URL 获取文件:', url)
|
|
|
|
|
|
- fetch(url)
|
|
|
+ fetch(url, {mode: 'cors'})
|
|
|
.then(response => {
|
|
|
if (!response.ok) {
|
|
|
console.error('HTTP 错误:', response.status, response.statusText)
|
|
|
@@ -1954,6 +1954,56 @@ export default () => {
|
|
|
})
|
|
|
}
|
|
|
|
|
|
+ // 纯 JS 跨域抓 HTML(最后兜底方案):通过公共 CORS 代理获取目标页面源码
|
|
|
+ // 用于 type=73 在 getHTML/getFile/getFile2 全部失败后的兜底
|
|
|
+ // 公共代理可用性不稳定(尤其国内网络),依次尝试多个,一个失败换下一个
|
|
|
+ const CORS_PROXIES: Array<(url: string) => string> = [
|
|
|
+ url => 'https://api.allorigins.win/raw?url=' + encodeURIComponent(url),
|
|
|
+ url => 'https://corsproxy.io/?url=' + encodeURIComponent(url),
|
|
|
+ url => 'https://api.codetabs.com/v1/proxy?quest=' + encodeURIComponent(url),
|
|
|
+ ]
|
|
|
+
|
|
|
+ const fetchViaProxy = (proxyFn: (url: string) => string, url: string): Promise<string> => {
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ const xhr = new XMLHttpRequest()
|
|
|
+ xhr.open('GET', proxyFn(url), true)
|
|
|
+ xhr.timeout = 12000 // iPad WebView 可能挂起不回调,必须加超时
|
|
|
+
|
|
|
+ xhr.onreadystatechange = function() {
|
|
|
+ if (xhr.readyState === 4) {
|
|
|
+ if (xhr.status === 200 && xhr.responseText) {
|
|
|
+ resolve(xhr.responseText)
|
|
|
+ }
|
|
|
+ else if (xhr.status !== 0) {
|
|
|
+ // status=0 是网络错误,交给 onerror 处理,避免重复 reject
|
|
|
+ reject(new Error('HTTP Error: ' + xhr.status))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ xhr.ontimeout = function() {
|
|
|
+ reject(new Error('Request Timeout'))
|
|
|
+ }
|
|
|
+ xhr.onerror = function() {
|
|
|
+ reject(new Error('Network Error'))
|
|
|
+ }
|
|
|
+ xhr.send()
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ const getHtmlPureJS = async (url: string): Promise<string> => {
|
|
|
+ let lastError: unknown = null
|
|
|
+ for (const proxyFn of CORS_PROXIES) {
|
|
|
+ try {
|
|
|
+ return await fetchViaProxy(proxyFn, url)
|
|
|
+ }
|
|
|
+ catch (err) {
|
|
|
+ console.warn('CORS 代理失败,尝试下一个:', proxyFn(url).slice(0, 50), err)
|
|
|
+ lastError = err
|
|
|
+ }
|
|
|
+ }
|
|
|
+ throw lastError || new Error('All proxies failed')
|
|
|
+ }
|
|
|
+
|
|
|
return {
|
|
|
importSpecificFile,
|
|
|
importJSON,
|
|
|
@@ -1964,6 +2014,7 @@ export default () => {
|
|
|
imgExporting,
|
|
|
getFile,
|
|
|
getFile2,
|
|
|
+ getHtmlPureJS,
|
|
|
dataToFile,
|
|
|
uploadFileToS3,
|
|
|
getPPTInfo
|