fix(creator-studio): 修复白屏与前台 REST 鉴权
白屏根因:CreatorRest / SubmissionVersion 位于 Jio\Core 命名空间, 但调用 Jio\Content\PrivateAssets 时缺少 use 导入,PHP 就近解析为不存在的 Jio\Core\PrivateAssets,在 wp_head 中抛致命错误导致页面输出截断。 - 为 CreatorRest、SubmissionVersion 补上 use Jio\Content\PrivateAssets - 新增前台 api-fetch nonce 中间件:WordPress 只在后台注入 wpApiSettings, 前台工作台里 Gutenberg core-data 请求(/wp/v2/users/me)因此全部 403 - 提交前先落一次草稿,避免自动保存未触发时发布到旧内容 - 新增 tools/check-class-refs.php:静态检测命名空间内未导入的裸类引用 - 新增 assets/creator-studio/scripts/smoke.cjs:浏览器冒烟脚本, 抓控制台错误、失败请求与未捕获的 Promise 拒绝 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
fac4a714e0
commit
2c7262770b
10 files changed
+262
-36
No files matched your search
@@ -17,6 +17,7 @@ import { count as countWords } from '@wordpress/wordcount';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
|
||||
import { apiPost } from './services/api';
|
||||
import { installApiFetchNonce } from './services/api-fetch';
|
||||
import { installMediaUploadBridge } from './services/media';
|
||||
import { PublishDrawer } from './panels/publish-drawer';
|
||||
import { SaveState, type SaveStateValue } from './components/save-state';
|
||||
@@ -183,6 +184,13 @@ function Studio(): JSX.Element {
|
||||
|
||||
const submit = useCallback(
|
||||
async (publishNow: boolean): Promise<void> => {
|
||||
// 提交前先落一次草稿:审核 / 立即发布都以服务端最终保存的内容为准,
|
||||
// 避免自动保存尚未触发时提交到旧内容。
|
||||
const persisted = await save(false);
|
||||
if (!persisted) {
|
||||
setNotice({ tone: 'error', text: __('内容保存失败,请重试后再提交', 'jio') });
|
||||
return;
|
||||
}
|
||||
setSaveState({ state: 'submitting', at: '' });
|
||||
try {
|
||||
// 站点启用「前台投稿」人机验证时,先完成挑战再提交;
|
||||
@@ -218,7 +226,7 @@ function Studio(): JSX.Element {
|
||||
setNotice({ tone: 'error', text: String(error?.message || __('提交失败', 'jio')) });
|
||||
}
|
||||
},
|
||||
[buildPayload]
|
||||
[buildPayload, save]
|
||||
);
|
||||
|
||||
const preview = useCallback(async (): Promise<void> => {
|
||||
@@ -436,6 +444,7 @@ function mount() {
|
||||
if (!target) {
|
||||
return;
|
||||
}
|
||||
installApiFetchNonce(nonce);
|
||||
installMediaUploadBridge(bootstrap, nonce);
|
||||
target.classList.add('is-ready');
|
||||
createRoot(target).render(<Studio />);
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* 给 @wordpress/api-fetch 注入 REST nonce。
|
||||
*
|
||||
* WordPress 仅在后台为 wp-api 注入 wpApiSettings(含 nonce),前台工作台里
|
||||
* Gutenberg 的 core-data 请求(如 /wp/v2/users/me)因此全部 403。这里统一挂一个
|
||||
* nonce 中间件,让区块编辑器的数据请求与 Jio REST 使用同一次页面加载的 nonce。
|
||||
*
|
||||
* @package Jio
|
||||
*/
|
||||
|
||||
import apiFetch from '@wordpress/api-fetch';
|
||||
|
||||
export function installApiFetchNonce(nonce: string): void {
|
||||
if (!nonce || typeof apiFetch.use !== 'function') {
|
||||
return;
|
||||
}
|
||||
if ((window as any).__jioApiFetchNonceInstalled) {
|
||||
return;
|
||||
}
|
||||
(window as any).__jioApiFetchNonceInstalled = true;
|
||||
|
||||
// createNonceMiddleware 在收到 rest_cookie_invalid_nonce 时会带着 nonce 重试,
|
||||
// 比在每次请求上手工加 header 更稳妥。
|
||||
const factory = (apiFetch as any).createNonceMiddleware;
|
||||
if (typeof factory === 'function') {
|
||||
apiFetch.use(factory(nonce));
|
||||
return;
|
||||
}
|
||||
apiFetch.use((options: any, next: any) => {
|
||||
options.headers = { ...(options.headers || {}), 'X-WP-Nonce': nonce };
|
||||
return next(options);
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user