diff --git a/README.md b/README.md
index c02a0991..d31654e8 100644
--- a/README.md
+++ b/README.md
@@ -30,49 +30,49 @@ Note: Image upload availability refers to the installation
of [PicGo plugin1.9.0+](https://github.com/terwer/siyuan-plugin-picgo) and accurate
configuration.
-| Type | Platform | Status | PC Client | PC Image Upload | Docker | Docker Image Upload | Platform Image Upload | Docker Proxy | PC Proxy | Note |
-| :-------------------: | :---------------------: | :----: | :------------------: | :-------------: | :----------------------------------------------------: | :-----------------: | --------------------- | ------------- | --------- | :--------------------------------------------------------- |
-| Generic | Yuque | ✔ | Compatible | ✔ | Compatible | ✔ | Not Supported | Bundled Proxy | No | [Official Website](https://yuque.com) |
-| Generic | Notion | ✔ | Compatible | ✔ | Compatible | ✔ | Not Supported | Bundled Proxy | No | [Official Website](https://www.notion.so) |
-| Generic | Halo | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | Bundled Proxy | No | [Official Website](https://halo.run) |
-| Generic | Evernote | TODO | TODO | TODO | TODO | TODO | TODO | TODO | TODO | [Official Website](https://www.evernote.com) |
-| Generic | Github | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | No | No | [Official Website](https://github.com) |
-| Static Site Generator | Hexo | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | No | No | [Official Website](https://hexo.io/zh-cn/) |
-| Static Site Generator | Hugo | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | No | No | [Official Website](https://gohugo.io/) |
-| Static Site Generator | Jekyll | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | No | No | [Official Website](https://jekyllrb.com/) |
-| Static Site Generator | Vuepress | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | No | No | [Official Website](https://vuepress.vuejs.org/) |
-| Static Site Generator | Vuepress2 | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | No | No | [Official Website](https://v2.vuepress.vuejs.org/) |
-| Static Site Generator | Vitepress | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | No | No | [Official Website](https://vitepress.vuejs.org/) |
-| Static Site Generator | Antora | TODO | TODO | TODO | TODO | TODO | TODO | TODO | TODO | [Official Website](https://antora.org/) |
-| Static Site Generator | Docsify | TODO | TODO | TODO | TODO | TODO | TODO | TODO | TODO | [Official Website](https://docsify.js.org/) |
-| Git Hosting | Gitlab | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | No | No | [Official Website](https://gitlab.com/) |
-| Git Hosting | Gitlabhexo | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | No | No | [Official Website](https://gitlab.com/) |
-| Git Hosting | Gitlabhugo | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | No | No | [Official Website](https://gitlab.com/) |
-| Git Hosting | Gitlabjekyll | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | No | No | [Official Website](https://gitlab.com/) |
-| Git Hosting | Gitlabvuepress | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | No | No | [Official Website](https://gitlab.com/) |
-| Git Hosting | Gitlabvuepress2 | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | No | No | [Official Website](https://gitlab.com/) |
-| Git Hosting | Gitlabvitepress | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | No | No | [Official Website](https://gitlab.com/) |
-| Git Hosting | Gitlabantora | TODO | TODO | TODO | TODO | TODO | Supported | TODO | TODO | [Official Website](https://gitlab.com/) |
-| Git Hosting | Gitlabdocsify | TODO | TODO | TODO | TODO | TODO | Supported | TODO | TODO | [Official Website](https://gitlab.com/) |
-| Blog | Metaweblog | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | Bundled Proxy | No | [Official Website](http://xmlrpc.scripting.com/metaWeblog) |
-| Blog | CnBlogs | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | Bundled Proxy | No | [Official Website](https://cnblogs.com) |
-| Blog | Typecho | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | Bundled Proxy | No | [Official Website](https://typecho.org/) |
-| Blog | Jvue | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | Bundled Proxy | No | [Official Website](https://github.com/terwer/jvue) |
-| Blog | WordPress | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | Bundled Proxy | No | [Official Website](https://wordpress.org/) |
-| Blog | WordPress.com | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | Bundled Proxy | No | [Official Website](https://wordpress.com) |
-| Social Media | Zhihu | ✔ | Fully Compatible | ✔ | Partially Compatible, Requires PC Account Verification | ❌ | | | | [Official Website](https://www.zhihu.com/) |
-| Social Media | CSDN | ✔ | Fully Compatible | ✔ | Partially Compatible, Requires PC Account Verification | ❌ | | | | [Official Website](https://www.csdn.net/) |
-| Social Media | WeChat Official Account | ✔ | Fully Compatible | ✔ | Partially Compatible, Requires PC Account Verification | ❌ | | | | [Official Website](https://mp.weixin.qq.com/) |
-| Social Media | Jianshu | ✔ | Fully Compatible | ✔ | Partially Compatible, Requires PC Account Verification | ❌ | | | | [Official Website](https://www.jianshu.com/) |
-| Social Media | Juejin | ✔ | Fully Compatible | ✔ | Partially Compatible, Requires PC Account Verification | ❌ | | | | [Official Website](https://juejin.cn/) |
-| Community | 52pojie | TODO | TODO | TODO | TODO | TODO | TODO | TODO | TODO | [Official Website](https://www.52pojie.cn/) |
-| Community | Bilibili | TODO | TODO | TODO | TODO | TODO | TODO | TODO | TODO | [Official Website](https://www.bilibili.com/) |
-| Community | Xiaohongshu | TODO | TODO | TODO | TODO | TODO | TODO | TODO | TODO | [Official Website](https://www.xiaohongshu.com/) |
-| Community | Douban | TODO | TODO | TODO | TODO | TODO | TODO | TODO | TODO | [Official Website](https://www.douban.com/) |
-| Others | Xlog | TODO | TODO | TODO | TODO | TODO | TODO | TODO | TODO | [Official Website](https://xlog.cn/) |
-| Others | Mdnice | TODO | TODO | TODO | TODO | TODO | TODO | TODO | TODO | [Official Website](https://mdnice.com/) |
-| Others | Flowus | TODO | TODO | TODO | TODO | TODO | TODO | TODO | TODO | [Official Website](https://www.flowus.com/) |
-| Others | telegra.ph | ✔ | Partially Compatible | ❌ | Partially Compatible | ❌ | | | | [Official Website](https://telegra.ph) |
+| Type | Platform | Status | PC Client | PC Image Upload | Docker | Docker Image Upload | Platform Image Upload | Docker Proxy | PC Proxy | Note |
+| :-------------------: | :---------------------: | :----: | :------------------: | :-------------: | :------------------: | :-----------------: | --------------------- | ------------- | ------------ | :--------------------------------------------------------- |
+| Generic | Yuque | ✔ | Compatible | ✔ | Compatible | ✔ | Not Supported | Bundled Proxy | No | [Official Website](https://yuque.com) |
+| Generic | Notion | ✔ | Compatible | ✔ | Compatible | ✔ | Not Supported | Bundled Proxy | No | [Official Website](https://www.notion.so) |
+| Generic | Halo | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | Bundled Proxy | No | [Official Website](https://halo.run) |
+| Generic | Evernote | TODO | TODO | TODO | TODO | TODO | TODO | TODO | TODO | [Official Website](https://www.evernote.com) |
+| Generic | Github | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | No | No | [Official Website](https://github.com) |
+| Static Site Generator | Hexo | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | No | No | [Official Website](https://hexo.io/zh-cn/) |
+| Static Site Generator | Hugo | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | No | No | [Official Website](https://gohugo.io/) |
+| Static Site Generator | Jekyll | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | No | No | [Official Website](https://jekyllrb.com/) |
+| Static Site Generator | Vuepress | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | No | No | [Official Website](https://vuepress.vuejs.org/) |
+| Static Site Generator | Vuepress2 | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | No | No | [Official Website](https://v2.vuepress.vuejs.org/) |
+| Static Site Generator | Vitepress | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | No | No | [Official Website](https://vitepress.vuejs.org/) |
+| Static Site Generator | Antora | TODO | TODO | TODO | TODO | TODO | TODO | TODO | TODO | [Official Website](https://antora.org/) |
+| Static Site Generator | Docsify | TODO | TODO | TODO | TODO | TODO | TODO | TODO | TODO | [Official Website](https://docsify.js.org/) |
+| Git Hosting | Gitlab | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | No | No | [Official Website](https://gitlab.com/) |
+| Git Hosting | Gitlabhexo | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | No | No | [Official Website](https://gitlab.com/) |
+| Git Hosting | Gitlabhugo | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | No | No | [Official Website](https://gitlab.com/) |
+| Git Hosting | Gitlabjekyll | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | No | No | [Official Website](https://gitlab.com/) |
+| Git Hosting | Gitlabvuepress | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | No | No | [Official Website](https://gitlab.com/) |
+| Git Hosting | Gitlabvuepress2 | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | No | No | [Official Website](https://gitlab.com/) |
+| Git Hosting | Gitlabvitepress | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | No | No | [Official Website](https://gitlab.com/) |
+| Git Hosting | Gitlabantora | TODO | TODO | TODO | TODO | TODO | Supported | TODO | TODO | [Official Website](https://gitlab.com/) |
+| Git Hosting | Gitlabdocsify | TODO | TODO | TODO | TODO | TODO | Supported | TODO | TODO | [Official Website](https://gitlab.com/) |
+| Blog | Metaweblog | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | Bundled Proxy | No | [Official Website](http://xmlrpc.scripting.com/metaWeblog) |
+| Blog | CnBlogs | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | Bundled Proxy | No | [Official Website](https://cnblogs.com) |
+| Blog | Typecho | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | Bundled Proxy | No | [Official Website](https://typecho.org/) |
+| Blog | Jvue | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | Bundled Proxy | No | [Official Website](https://github.com/terwer/jvue) |
+| Blog | WordPress | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | Bundled Proxy | No | [Official Website](https://wordpress.org/) |
+| Blog | WordPress.com | ✔ | Compatible | ✔ | Compatible | ✔ | Supported | Bundled Proxy | No | [Official Website](https://wordpress.com) |
+| Social Media | Zhihu | ✔ | Fully Compatible | ✔ | Requires PC Auth | ✖ | Supported | Bundled Proxy | No | [Official Website](https://www.zhihu.com/) |
+| Social Media | CSDN | ✔ | Fully Compatible | ✔ | Requires PC Auth | ✖ | Supported | Bundled Proxy | No | [Official Website](https://www.csdn.net/) |
+| Social Media | WeChat Official Account | ✔ | Fully Compatible | ✔ | Requires PC Auth | ✖ | Supported | Bundled Proxy | No | [Official Website](https://mp.weixin.qq.com/) |
+| Social Media | Jianshu | ✔ | Fully Compatible | ✔ | Requires PC Auth | ✖ | Supported | Bundled Proxy | No | [Official Website](https://www.jianshu.com/) |
+| Social Media | Juejin | ✔ | Fully Compatible | ✔ | Requires PC Auth | ✔ | Not Supported | Bundled Proxy | No | [Official Website](https://juejin.cn/) |
+| Community | 52pojie | TODO | TODO | TODO | TODO | TODO | TODO | TODO | TODO | [Official Website](https://www.52pojie.cn/) |
+| Community | Bilibili | TODO | TODO | TODO | TODO | TODO | TODO | TODO | TODO | [Official Website](https://www.bilibili.com/) |
+| Community | Xiaohongshu | TODO | TODO | TODO | TODO | TODO | TODO | TODO | TODO | [Official Website](https://www.xiaohongshu.com/) |
+| Community | Douban | TODO | TODO | TODO | TODO | TODO | TODO | TODO | TODO | [Official Website](https://www.douban.com/) |
+| Others | Xlog | TODO | TODO | TODO | TODO | TODO | TODO | TODO | TODO | [Official Website](https://xlog.cn/) |
+| Others | Mdnice | TODO | TODO | TODO | TODO | TODO | TODO | TODO | TODO | [Official Website](https://mdnice.com/) |
+| Others | Flowus | TODO | TODO | TODO | TODO | TODO | TODO | TODO | TODO | [Official Website](https://www.flowus.com/) |
+| Others | telegra.ph | ✔ | Partially Compatible | ✖ | Partially Compatible | ✖ | Not Supported | Custom Proxy | Custom Proxy | [Official Website](https://telegra.ph) |
## Core Features
diff --git a/README_zh_CN.md b/README_zh_CN.md
index 2d0d8978..847b1cd1 100644
--- a/README_zh_CN.md
+++ b/README_zh_CN.md
@@ -57,11 +57,11 @@
| 博客 | Jvue | ✔ | 完全兼容 | ✔ | 完全兼容 | ✔ | 支持 | 内置代理 | 不需要 | [官网](https://github.com/terwer/jvue) |
| 博客 | WordPress | ✔ | 完全兼容 | ✔ | 完全兼容 | ✔ | 支持 | 内置代理 | 不需要 | [官网](https://wordpress.org/) |
| 博客 | WordPress.com | ✔ | 完全兼容 | ✔ | 完全兼容 | ✔ | 支持 | 内置代理 | 不需要 | [官网](https://wordpress.com) |
-| 社交媒体 | 知乎 | ✔ | 完全兼容 | ✔ | PC 验证 | ✖ | | | | [官网](https://www.zhihu.com/) |
-| 社交媒体 | CSDN | ✔ | 完全兼容 | ✔ | PC 验证 | ✖ | | | | [官网](https://www.csdn.net/) |
-| 社交媒体 | 微信公众号 | ✔ | 完全兼容 | ✔ | PC 验证 | ✖ | | | | [官网](https://mp.weixin.qq.com/) |
-| 社交媒体 | 简书 | ✔ | 完全兼容 | ✔ | PC 验证 | ✖ | | | | [官网](https://www.jianshu.com/) |
-| 社交媒体 | 掘金 | ✔ | 完全兼容 | ✔ | PC 验证 | ✔ | | | | [官网](https://juejin.cn/) |
+| 社交媒体 | 知乎 | ✔ | 完全兼容 | ✔ | PC 验证 | ✖ | 支持 | 内置代理 | 不需要 | [官网](https://www.zhihu.com/) |
+| 社交媒体 | CSDN | ✔ | 完全兼容 | ✔ | PC 验证 | ✖ | 支持 | 内置代理 | 不需要 | [官网](https://www.csdn.net/) |
+| 社交媒体 | 微信公众号 | ✔ | 完全兼容 | ✔ | PC 验证 | ✖ | 支持 | 内置代理 | 不需要 | [官网](https://mp.weixin.qq.com/) |
+| 社交媒体 | 简书 | ✔ | 完全兼容 | ✔ | PC 验证 | ✖ | 支持 | 内置代理 | 不需要 | [官网](https://www.jianshu.com/) |
+| 社交媒体 | 掘金 | ✔ | 完全兼容 | ✔ | PC 验证 | ✔ | 不支持 | 内置代理 | 不需要 | [官网](https://juejin.cn/) |
| 社区 | 52破解 | TODO | TODO | TODO | TODO | TODO | TODO | TODO | TODO | [官网](https://www.52pojie.cn/) |
| 社区 | Bilibili | TODO | TODO | TODO | TODO | TODO | TODO | TODO | TODO | [官网](https://www.bilibili.com/) |
| 社区 | 小红书 | TODO | TODO | TODO | TODO | TODO | TODO | TODO | TODO | [官网](https://www.xiaohongshu.com/) |
@@ -69,7 +69,7 @@
| 其他 | Xlog | TODO | TODO | TODO | TODO | TODO | TODO | TODO | TODO | [官网](https://xlog.cn/) |
| 其他 | Mdnice | TODO | TODO | TODO | TODO | TODO | TODO | TODO | TODO | [官网](https://mdnice.com/) |
| 其他 | Flowus | TODO | TODO | TODO | TODO | TODO | TODO | TODO | TODO | [官网](https://www.flowus.com/) |
-| 其他 | telegra.ph | ✔ | 部分兼容 | ✖ | 部分兼容 | ✖ | | | | [官网](https://telegra.ph) |
+| 其他 | telegra.ph | ✔ | 部分兼容 | ✖ | 部分兼容 | ✖ | 不支持 | 自建代理 | 自建代理 | [官网](https://telegra.ph) |
## 核心特色
diff --git a/src/adaptors/api/base/baseBlogApi.ts b/src/adaptors/api/base/baseBlogApi.ts
index b5be6a01..6131d62f 100644
--- a/src/adaptors/api/base/baseBlogApi.ts
+++ b/src/adaptors/api/base/baseBlogApi.ts
@@ -28,7 +28,7 @@ import { PublisherAppInstance } from "~/src/publisherAppInstance.ts"
import { createAppLogger, ILogger } from "~/src/utils/appLogger.ts"
import { useProxy } from "~/src/composables/useProxy.ts"
import { BaseExtendApi } from "~/src/adaptors/base/baseExtendApi.ts"
-import { JsonUtil, StrUtil } from "zhi-common"
+import { JsonUtil } from "zhi-common"
import { useSiyuanDevice } from "~/src/composables/useSiyuanDevice.ts"
import { Base64 } from "js-base64"
import FormDataUtils from "~/src/utils/FormDataUtils.ts"
@@ -132,29 +132,36 @@ export class BaseBlogApi extends BlogApi {
| "base32-hex"
| "hex" = "text"
) {
- const isCorsProxyAvailable = !StrUtil.isEmptyString(this.cfg.corsAnywhereUrl)
+ const header = headers.length > 0 ? headers[0] : {}
+
// 如果没有可用的 CORS 代理或者没有强制使用代理,使用默认的自动检测机制
- if (this.isUseSiyuanProxy || !isCorsProxyAvailable) {
- this.logger.info("Using legency api fetch")
- // const proxyFetch = async (
- // url: string,
- // headers: any[] = [],
- // params: any = {},
- // method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH" = "GET",
- // contentType: string = "application/json",
- // forceProxy: boolean = false
- // ) => {
+ if (this.isUseSiyuanProxy || (!this.isUseSiyuanProxy && forceProxy)) {
this.logger.info("Using legency api fetch")
- return this.proxyFetch(url, headers, params, method, contentType, forceProxy, payloadEncoding, responseEncoding)
+ // remove cors fetch header
+ delete header["x-cors-headers"]
+ const blogHeaders = [
+ {
+ ...header,
+ },
+ ]
+ return this.proxyFetch(
+ url,
+ blogHeaders,
+ params,
+ method,
+ contentType,
+ forceProxy,
+ payloadEncoding,
+ responseEncoding
+ )
} else {
- // const corsFetch = async (
- // url: string,
- // headers: any[] = [],
- // params: BodyInit = undefined,
- // method: "GET" | "POST" | "PUT" | "DELETE" = "GET"
- // )
this.logger.info("Using cors api fetch")
- return this.corsFetch(url, headers, params, method)
+ const blogHeaders = [
+ {
+ ...header,
+ },
+ ]
+ return this.corsFetch(url, blogHeaders, params, method)
}
}
@@ -167,13 +174,12 @@ export class BaseBlogApi extends BlogApi {
* @param forceProxy - 是否强制使用代理,默认为 false
*/
public async apiProxyFormFetch(url: string, headers: any[], formData: FormData, forceProxy: boolean = false) {
- const isCorsProxyAvailable = !StrUtil.isEmptyString(this.cfg.corsAnywhereUrl)
// 如果没有可用的 CORS 代理或者没有强制使用代理,使用默认的自动检测机制
- if (this.isUseSiyuanProxy || !isCorsProxyAvailable) {
+ if (this.isUseSiyuanProxy || (!this.isUseSiyuanProxy && forceProxy)) {
this.logger.info("Using legency api formFetch")
const { isInSiyuanOrSiyuanNewWin } = useSiyuanDevice()
- if (!isInSiyuanOrSiyuanNewWin()) {
+ if (!isInSiyuanOrSiyuanNewWin() || forceProxy) {
const fetchResult = await this.apiProxyFetch(
url,
headers,
diff --git a/src/adaptors/api/telegraph/telegraphApiAdaptor.ts b/src/adaptors/api/telegraph/telegraphApiAdaptor.ts
index b46cd987..b8c19e76 100644
--- a/src/adaptors/api/telegraph/telegraphApiAdaptor.ts
+++ b/src/adaptors/api/telegraph/telegraphApiAdaptor.ts
@@ -29,6 +29,7 @@ import { TelegraphConfig } from "~/src/adaptors/api/telegraph/telegraphConfig.ts
import { JsonUtil, StrUtil } from "zhi-common"
import CookieUtils from "~/src/utils/cookieUtils.ts"
import md from "telegraph.md"
+import FormDataUtils from "~/src/utils/FormDataUtils.ts"
/**
* Telegraph API 适配器
@@ -41,14 +42,31 @@ class TelegraphApiAdaptor extends BaseBlogApi {
public async getUsersBlogs(): Promise {
const result: UserBlog[] = []
- const checkJson = await this.telegraphFetch("/check", "page_id=0", "POST")
- if (checkJson.error) {
- throw new Error("telegra.ph request error =>" + checkJson.error)
- }
- const corsHeaders = JsonUtil.safeParse(checkJson["cors-received-headers"], {})
- const cookies = corsHeaders["Set-Cookie-Array"]
+ let cookies: any
+ let checkJson = await this.telegraphFetch("/check", "page_id=0", "POST")
this.logger.debug("checkJson =>", checkJson)
+ if (checkJson["cors-received-headers"]) {
+ // use cors proxy
+ if (checkJson.error) {
+ throw new Error("telegra.ph request error =>" + checkJson.error)
+ }
+ const corsHeaders = JsonUtil.safeParse(checkJson["cors-received-headers"], {})
+ cookies = corsHeaders["Set-Cookie-Array"]
+ } else {
+ // use siyuan proxy
+ if (checkJson.status == 200) {
+ cookies = checkJson.headers["Set-Cookie"]
+ const body = JsonUtil.safeParse(checkJson.body, {})
+ checkJson = {
+ ...checkJson,
+ ...body,
+ }
+ } else {
+ throw new Error(`telegra.ph request error ${checkJson.status}=>` + checkJson.body)
+ }
+ }
+
// 数据适配
const userblog: UserBlog = new UserBlog()
const cfg = this.cfg as TelegraphConfig
@@ -57,9 +75,10 @@ class TelegraphApiAdaptor extends BaseBlogApi {
userblog.url = cfg.apiUrl
// 元数据映射
// @since 1.20.0
+ const newCookies = CookieUtils.addCookieArray(this.cfg?.corsCookieArray ?? [], cookies)
userblog.metadataMap = {
password: checkJson.save_hash,
- corsCookieArray: CookieUtils.addCookieArray(this.cfg?.corsCookieArray ?? [], cookies),
+ corsCookieArray: newCookies,
}
result.push(userblog)
this.logger.debug("get telegraph cfg =>", result)
@@ -68,6 +87,9 @@ class TelegraphApiAdaptor extends BaseBlogApi {
}
public async newPost(post: Post, _publish?: boolean): Promise {
+ // 这里不用这个,因为 telegraph 必须强制代理
+ // const { FormData, Blob } = FormDataUtils.getFormData(this.appInstance)
+
const formData = new FormData()
const content = md(post.description)
const blobData = new Blob([JSON.stringify(content)], { type: "text/plain" })
@@ -95,6 +117,8 @@ class TelegraphApiAdaptor extends BaseBlogApi {
}
public async editPost(postid: string, post: Post, publish?: boolean): Promise {
+ const { FormData, Blob } = FormDataUtils.getFormData(this.appInstance)
+
const postMeta = JsonUtil.safeParse(postid, {})
const formData = new FormData()
@@ -153,16 +177,39 @@ class TelegraphApiAdaptor extends BaseBlogApi {
header: Record = {}
) {
const contentType = "text/plain"
+ // const tphUuidObj = CookieUtils.getCookieObject(this.cfg.corsCookieArray, this.TPH_UUID_KEY)
+ // if (!StrUtil.isEmptyString(tphUuidObj[this.TPH_UUID_KEY])) {
+ // header["Cookie"] = `${this.TPH_UUID_KEY}=${tphUuidObj[this.TPH_UUID_KEY]}`
+ // }
+
+ // const headers = {
+ // "Content-Type": contentType,
+ // origin: "https://telegra.ph",
+ // referer: "https://telegra.ph/",
+ // ...header,
+ // }
+ let xCorsHeaders: Record = {}
+
+ // header
+
+ // x-cors-headers
const tphUuidObj = CookieUtils.getCookieObject(this.cfg.corsCookieArray, this.TPH_UUID_KEY)
if (!StrUtil.isEmptyString(tphUuidObj[this.TPH_UUID_KEY])) {
- header["Cookie"] = `${this.TPH_UUID_KEY}=${tphUuidObj[this.TPH_UUID_KEY]}`
+ xCorsHeaders["Cookie"] = `${this.TPH_UUID_KEY}=${tphUuidObj[this.TPH_UUID_KEY]}`
}
+ xCorsHeaders["origin"] = "https://telegra.ph"
+ xCorsHeaders["referer"] = "https://telegra.ph/"
+ xCorsHeaders["Content-Type"] = contentType
+
const headers = {
- "Content-Type": contentType,
- origin: "https://telegra.ph",
- referer: "https://telegra.ph/",
- ...header,
+ // for cors proxy
+ // siyuan proxy should ignore this header
+ "x-cors-headers": JSON.stringify(xCorsHeaders),
+ }
+ for (const [xkey, xvalue] of Object.entries(xCorsHeaders)) {
+ headers[xkey] = xvalue
}
+
const body = params
// 输出日志
@@ -172,7 +219,7 @@ class TelegraphApiAdaptor extends BaseBlogApi {
this.logger.debug("向 Telegraph 请求数据,headers =>", headers)
this.logger.debug("向 Telegraph 请求数据,body =>", body)
- const resJson = await this.apiProxyFetch(apiUrl, [headers], body, method, contentType, true)
+ const resJson = await this.apiProxyFetch(apiUrl, [headers], body, method, contentType, false)
this.logger.debug("向 Telegraph 请求数据,resJson =>", resJson)
return resJson ?? null
@@ -199,8 +246,14 @@ class TelegraphApiAdaptor extends BaseBlogApi {
xCorsHeaders["referer"] = "https://telegra.ph/"
const headers = {
+ // for cors proxy
+ // siyuan proxy should ignore this header
"x-cors-headers": JSON.stringify(xCorsHeaders),
}
+ for (const [xkey, xvalue] of Object.entries(xCorsHeaders)) {
+ headers[xkey] = xvalue
+ }
+
const options: RequestInit = {
method: "POST",
headers: headers,
@@ -210,7 +263,7 @@ class TelegraphApiAdaptor extends BaseBlogApi {
this.logger.debug("向 Telegraph 发送表单数据,apiUrl =>", apiUrl)
this.logger.debug("向 Telegraph 发送表单数据,options =>", options)
- const resJson = await this.apiProxyFormFetch(apiUrl, [headers], formData, true)
+ const resJson = await this.apiProxyFormFetch(apiUrl, [headers], formData, false)
if (resJson.error) {
throw new Error(
"telegra.ph 发布错误,注意:切换设备(包括从PC到浏览器环境)需要重新验证,并且获取新token。详细错误 =>" +
diff --git a/src/adaptors/api/telegraph/useTelegraphApi.ts b/src/adaptors/api/telegraph/useTelegraphApi.ts
index c7c01238..0833e19c 100644
--- a/src/adaptors/api/telegraph/useTelegraphApi.ts
+++ b/src/adaptors/api/telegraph/useTelegraphApi.ts
@@ -31,7 +31,7 @@ import { JsonUtil, ObjectUtil, StrUtil } from "zhi-common"
import { Utils } from "~/src/utils/utils.ts"
import { getDynPostidKey } from "~/src/platforms/dynamicConfig.ts"
import { TelegraphApiAdaptor } from "~/src/adaptors/api/telegraph/telegraphApiAdaptor.ts"
-import { CORS_PROXT_URL, LEGENCY_SHARED_PROXT_MIDDLEWARE } from "~/src/utils/constants.ts"
+import { LEGENCY_SHARED_PROXT_MIDDLEWARE } from "~/src/utils/constants.ts"
const useTelegraphApi = async (key: string, newCfg?: TelegraphConfig) => {
const logger = createAppLogger("use-telegraph-api")
@@ -51,7 +51,7 @@ const useTelegraphApi = async (key: string, newCfg?: TelegraphConfig) => {
if (ObjectUtil.isEmptyObject(cfg)) {
const telegraphUrl = Utils.emptyOrDefault(process.env.VITE_TELEGRAPH_URL, "https://telegra.ph")
const middlewareUrl = Utils.emptyOrDefault(process.env.VITE_MIDDLEWARE_URL, LEGENCY_SHARED_PROXT_MIDDLEWARE)
- const telegraphToken = Utils.emptyOrDefault(process.env.VITE_TELEGRAPH_TOKEN, CORS_PROXT_URL)
+ const telegraphToken = Utils.emptyOrDefault(process.env.VITE_TELEGRAPH_TOKEN, "")
cfg = new TelegraphConfig(telegraphUrl, telegraphToken, middlewareUrl)
logger.info("Configuration is empty, using default environment variables.")
} else {
@@ -63,11 +63,6 @@ const useTelegraphApi = async (key: string, newCfg?: TelegraphConfig) => {
// 默认值
cfg.posidKey = getDynPostidKey(key)
}
- // 初始化corsAnywhereUrl
- if (StrUtil.isEmptyString(cfg.corsAnywhereUrl)) {
- // 默认值
- cfg.corsAnywhereUrl = Utils.emptyOrDefault(process.env.VITE_CORS_ANYWHERE_URL, CORS_PROXT_URL)
- }
}
cfg.usernameEnabled = true
diff --git a/src/adaptors/web/base/baseWebApi.ts b/src/adaptors/web/base/baseWebApi.ts
index 53af7d95..6ff5c5a6 100644
--- a/src/adaptors/web/base/baseWebApi.ts
+++ b/src/adaptors/web/base/baseWebApi.ts
@@ -192,17 +192,17 @@ class BaseWebApi extends WebApi {
| "hex" = "text"
) {
const header = headers.length > 0 ? headers[0] : {}
- const webHeaders = [
- {
- ...header,
- Cookie: this.cfg.password,
- },
- ]
-
- const isCorsProxyAvailable = !StrUtil.isEmptyString(this.cfg.corsAnywhereUrl)
// 如果没有可用的 CORS 代理或者没有强制使用代理,使用默认的自动检测机制
- if (this.isUseSiyuanProxy || !isCorsProxyAvailable) {
+ if (this.isUseSiyuanProxy || (!this.isUseSiyuanProxy && forceProxy)) {
this.logger.info("Using legency web fetch")
+ // remove cors fetch header
+ delete header["x-cors-headers"]
+ const webHeaders = [
+ {
+ ...header,
+ Cookie: this.cfg.password,
+ },
+ ]
return await this.proxyFetch(
url,
webHeaders,
@@ -215,7 +215,13 @@ class BaseWebApi extends WebApi {
)
} else {
this.logger.info("Using cors web fetch")
- return this.corsFetch(url, headers, params, method)
+ const webHeaders = [
+ {
+ ...header,
+ Cookie: this.cfg.password,
+ },
+ ]
+ return this.corsFetch(url, webHeaders, params, method)
}
}
@@ -253,13 +259,12 @@ class BaseWebApi extends WebApi {
| "base32-hex"
| "hex" = "text"
) {
- const isCorsProxyAvailable = !StrUtil.isEmptyString(this.cfg.corsAnywhereUrl)
// 如果没有可用的 CORS 代理或者没有强制使用代理,使用默认的自动检测机制
- if (this.isUseSiyuanProxy || !isCorsProxyAvailable) {
+ if (this.isUseSiyuanProxy || (!this.isUseSiyuanProxy && forceProxy)) {
this.logger.info("Using legency web formFetch")
const { isInSiyuanOrSiyuanNewWin } = useSiyuanDevice()
- if (!isInSiyuanOrSiyuanNewWin()) {
+ if (!isInSiyuanOrSiyuanNewWin() || forceProxy) {
const fetchResult = await this.webProxyFetch(
url,
headers,
diff --git a/src/adaptors/web/csdn/csdnWebAdaptor.ts b/src/adaptors/web/csdn/csdnWebAdaptor.ts
index 956534b5..91891b14 100644
--- a/src/adaptors/web/csdn/csdnWebAdaptor.ts
+++ b/src/adaptors/web/csdn/csdnWebAdaptor.ts
@@ -29,6 +29,7 @@ import { BlogConfig, CategoryInfo, PageTypeEnum, Post, UserBlog } from "zhi-blog
import { JsonUtil } from "zhi-common"
import WebUtils from "~/src/adaptors/web/base/webUtils.ts"
import _ from "lodash-es"
+import FormDataUtils from "~/src/utils/FormDataUtils.ts";
/**
* CSDN网页授权适配器
@@ -303,6 +304,8 @@ class CsdnWebAdaptor extends BaseWebApi {
}
public async uploadFile(file: File | Blob, filename?: string): Promise {
+ const { FormData, Blob } = FormDataUtils.getFormData(this.appInstance)
+
this.logger.debug(`csdn start uploadFile ${filename}=>`, file)
if (file instanceof Blob) {
const uploadData = await this.requestUpload(filename)
diff --git a/src/adaptors/web/jianshu/jianshuWebAdaptor.ts b/src/adaptors/web/jianshu/jianshuWebAdaptor.ts
index 012f4c18..3814a8e0 100644
--- a/src/adaptors/web/jianshu/jianshuWebAdaptor.ts
+++ b/src/adaptors/web/jianshu/jianshuWebAdaptor.ts
@@ -182,6 +182,8 @@ class JianshuWebAdaptor extends BaseWebApi {
}
public async uploadFile(file: File | Blob, filename?: string): Promise {
+ const { FormData, Blob } = FormDataUtils.getFormData(this.appInstance)
+
this.logger.debug(`jianshu start uploadFile ${filename}=>`, file)
if (file instanceof Blob) {
// import
@@ -189,7 +191,6 @@ class JianshuWebAdaptor extends BaseWebApi {
if (!win.require) {
throw new Error("非常抱歉,目前仅思源笔记PC客户端支持上传图片")
}
- const { FormData, Blob } = FormDataUtils.getFormData(this.appInstance)
// uploadUrl
const uploadUrl = "https://upload.qiniup.com/"
diff --git a/src/adaptors/web/wechat/wechatWebAdaptor.ts b/src/adaptors/web/wechat/wechatWebAdaptor.ts
index 9f40b5f1..84b01709 100644
--- a/src/adaptors/web/wechat/wechatWebAdaptor.ts
+++ b/src/adaptors/web/wechat/wechatWebAdaptor.ts
@@ -443,6 +443,9 @@ class WechatWebAdaptor extends BaseWebApi {
}
public async uploadFile(file: File | Blob, filename?: string): Promise {
+ // get formData and Blob
+ const { FormData, Blob } = FormDataUtils.getFormData(this.appInstance)
+
this.logger.debug(`wechat start uploadFile ${filename}=>`, file)
if (file instanceof Blob) {
// import
@@ -450,7 +453,6 @@ class WechatWebAdaptor extends BaseWebApi {
if (!win.require) {
throw new Error("非常抱歉,目前仅思源笔记PC客户端支持上传图片")
}
- const { FormData, Blob } = FormDataUtils.getFormData(this.appInstance)
// uploadUrl
const ticket_id = this.cfg.metadata.commonData.data.user_name
@@ -535,6 +537,8 @@ class WechatWebAdaptor extends BaseWebApi {
*/
private async wechatFetch(url: string, params: Record) {
this.logger.debug("before getFormdataFetch, params =>", params)
+ // get formData and Blob
+ const { FormData } = FormDataUtils.getFormData(this.appInstance)
// formData
const formData: any = new FormData()
diff --git a/src/components/set/publish/singleplatform/base/CommonBlogSetting.vue b/src/components/set/publish/singleplatform/base/CommonBlogSetting.vue
index ed19be94..41fe6ac0 100644
--- a/src/components/set/publish/singleplatform/base/CommonBlogSetting.vue
+++ b/src/components/set/publish/singleplatform/base/CommonBlogSetting.vue
@@ -470,7 +470,7 @@ onMounted(async () => {
@@ -483,7 +483,7 @@ onMounted(async () => {
diff --git a/src/composables/useProxy.ts b/src/composables/useProxy.ts
index 9b4665b0..52c5cf4d 100644
--- a/src/composables/useProxy.ts
+++ b/src/composables/useProxy.ts
@@ -26,11 +26,10 @@
import { useSiyuanApi } from "~/src/composables/useSiyuanApi.ts"
import { JsonUtil, ObjectUtil, StrUtil } from "zhi-common"
import { CommonFetchClient } from "zhi-fetch-middleware"
-import { CORS_PROXT_URL, isDev, LEGENCY_SHARED_PROXT_MIDDLEWARE } from "~/src/utils/constants.ts"
+import { isDev, LEGENCY_SHARED_PROXT_MIDDLEWARE } from "~/src/utils/constants.ts"
import { PublisherAppInstance } from "~/src/publisherAppInstance.ts"
import { createAppLogger } from "~/src/utils/appLogger.ts"
import { Deserializer, Serializer, XmlrpcUtil } from "simple-xmlrpc"
-import { Base64 } from "js-base64"
/**
* 用于处理代理请求的自定义 hook
@@ -51,7 +50,7 @@ const useProxy = (middlewareUrl?: string, corsProxyUrl?: string) => {
const appInstance = new PublisherAppInstance()
const apiUrl = ""
middlewareUrl = middlewareUrl ?? LEGENCY_SHARED_PROXT_MIDDLEWARE
- corsProxyUrl = corsProxyUrl ?? CORS_PROXT_URL
+ corsProxyUrl = corsProxyUrl ?? ""
const commonFetchClient = new CommonFetchClient(appInstance, apiUrl, middlewareUrl, isDev)
const serializer = new Serializer(appInstance)
@@ -93,18 +92,9 @@ const useProxy = (middlewareUrl?: string, corsProxyUrl?: string) => {
| "base32-hex"
| "hex" = "text"
) => {
- if (isUseSiyuanProxy) {
+ if (isUseSiyuanProxy || (!isUseSiyuanProxy && forceProxy)) {
logger.info("Using Siyuan forwardProxy")
- return await siyuanProxyFetch(
- url,
- headers,
- params,
- method,
- contentType,
- forceProxy,
- payloadEncoding,
- responseEncoding
- )
+ return await siyuanProxyFetch(url, headers, params, method, contentType, payloadEncoding, responseEncoding)
} else {
logger.info("Using middleware proxy fetch")
const header = headers.length > 0 ? headers[0] : {}
@@ -223,7 +213,6 @@ const useProxy = (middlewareUrl?: string, corsProxyUrl?: string) => {
* @param params - 请求的参数
* @param method - 请求的 HTTP 方法
* @param contentType - 请求的内容类型
- * @param forceProxy - 是否强制使用代理
* @param payloadEncoding - 请求体的编码方式,默认为 text
* @param responseEncoding - 响应体的编码方式,默认为 text
*/
@@ -233,7 +222,6 @@ const useProxy = (middlewareUrl?: string, corsProxyUrl?: string) => {
params: any = {},
method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH" = "GET",
contentType: string = "application/json",
- forceProxy: boolean = false,
payloadEncoding:
| "text"
| "base64"
diff --git a/src/utils/constants.ts b/src/utils/constants.ts
index c339a4fd..49e6bd0e 100644
--- a/src/utils/constants.ts
+++ b/src/utils/constants.ts
@@ -34,7 +34,6 @@ export const aboutUrl = "https://terwer.space/about"
*/
export const DYNAMIC_CONFIG_KEY = "dynamic-config"
-
/**
* 自动映射分类占位符
*/
@@ -54,9 +53,9 @@ export const MAX_TITLE_LENGTH = 10
export const LEGENCY_SHARED_PROXT_MIDDLEWARE = "https://api.terwer.space/api/middleware"
/**
- * 新版通用 HTTP 代理
+ * 新版通用 HTTP 代理,不再免费提供
*
- * @since 1.20.0
- * @version 1.20.0
+ * @since 1.20.2
+ * @version 1.20.2
*/
-export const CORS_PROXT_URL = "https://cors.terwer.space"
+// export const CORS_PROXT_URL = ""
diff --git a/testdata/telegra-ph/telegra.ph.http b/testdata/telegra-ph/telegra.ph.http
index ac2a675c..c9bb759f 100644
--- a/testdata/telegra-ph/telegra.ph.http
+++ b/testdata/telegra-ph/telegra.ph.http
@@ -1,6 +1,7 @@
# telegra.ph
### getCfg
+# @no-cookie-jar
POST https://edit.telegra.ph/check
origin: https://telegra.ph
referer: https://telegra.ph/
@@ -9,9 +10,12 @@ Content-Type: text/plain
page_id=0
### newArticle
+# @no-cookie-jar
POST https://edit.telegra.ph/save
origin: https://telegra.ph
referer: https://telegra.ph/
+Cookie: tph_uuid=E8eRGiWLjdx4Qbs0csRuQz2tBniMZQ1DYguCwroNET
+#Cookie: tph_uuid=OA4kiCWNRETS7Laf9JLG5m5yDG7IQh2CP4W8GQTvvM
Content-Type: multipart/form-data; boundary=TelegraPhBoundary21
--TelegraPhBoundary21