Strapi踩坑记录
date
Jun 4, 2023
slug
strapiklnadf
status
Published
tags
Node
summary
type
Post
提醒!
1、建议对Strapi有源文件修改后均
yarn build && yarn develop
,避免代码未生效;
2、本文内容是基于v4.10.7;安装中文
1、安装中文语言包
点击
admin/settings/internationalization
进入,或手动在后台找到【设置 → 全局设置 → 国际化】,右上角点击【添加语言】,选择Chinese (Simplified) (zh-Hans)
后保存。将
src/admin
下app.example.tsx
重命名为app.tsx
,其中 config.locales 中保留'zh-Hans’
,其他语言均注释掉。然后重启程序!!!
2、首选语言更新为中文
打开后台左下角个人资料中,找到语言设置,更新为【中文(简体)】,点击右上角保存,页面自动刷新为中文。
子路径访问
原始需求:CMS服务部署为子路径,和其他服务共享同一个域名,通过Nginx实现反向代理。
阅读Strapi官方文档之后,发现 config 目录下这3个文件均有关于路径的配置:
server.ts
:中的 url(简称A,默认值为''
)是用来配置对外访问的地址,比如重置密码、第三方调用的路径,如https://mywebsite.com/
,阅读源码发现该字段也兼容相对路径,如/cms
。
admin.ts
:中的 url(简称B,默认值为/admin
)是用来配置管理后台的地址,完整路径则为A + B
。假设A为/cms
,那么后台访问地址为/cms/admin
。
api.ts
:中的 rest.prefix (简称C,默认值为/api
)只对外接口的地址,不包含admin中用到的地址,完整路径则为A + C
。
这时访问会提示 http://localhost:1337/cms/admin 会提示【警告:请求 API 时发生错误】,下面开始踩坑分析:
1、上述A、B、C分别设置相对路径后,启动后发现管理后台的接口请求报错,以为是A必须设置为绝对路径,接着就分析关于A\B路径使用的源码,最终发现A是可相对路径的。
然后关键点在于设置B,需更新strapi/lib/services/server/admin-api.js的prefix的值。
const { createAPI } = require('./api');
const createAdminAPI = (strapi) => {
const opts = {
// 【笔者注】官方源内容
// prefix: '', // '/admin';
// 【笔者注】新内容
prefix: strapi.config.get('server.url', ''),
type: 'admin',
};
return createAPI(strapi, opts);
};
module.exports = { createAdminAPI };
其次关键点在于设置C,需更新strapi/lib/services/server/content-api.js的值,否则影响documentation插件的在线预览。
const { createAPI } = require('./api');
const createContentAPI = (strapi) => {
const opts = {
// 【笔者注】官方源内容
// prefix: strapi.config.get('api.rest.prefix', '/api'),
// 【笔者注】新内容
prefix: strapi.config.get('server.url', '') + strapi.config.get('api.rest.prefix', '/api'),
type: 'content-api',
};
return createAPI(strapi, opts);
};
module.exports = {
createContentAPI,
};
2、这时通过http://localhost:1337/cms/admin已能正常使用使用。刚好看到Strapi的Nginx Proxying内容
# path: /etc/nginx/sites-available/strapi.conf
# Strapi server
upstream strapi {
server 127.0.0.1:1337;
}
server {
listen 80;
server_name strapi.local.com;
# Strapi API and Admin
location /cms/ {
rewrite ^/cms/?(.*)$ /$1 break;
proxy_pass http://strapi;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass_request_headers on;
}
}
{"data":null,"error":{"status":404,"name":"NotFoundError","message":"Not Found","details":{}}}
所以需将nginx代理配置更新如下
location /cms {
proxy_pass http://127.0.0.1:1337/cms;
# 其他proxy_header相关的按需配置吧
}
至此,通过Nginx实现Strapi的子路径访问需求完成。
插件配置
1、通过官方教程生成的工程,会在package.json里包含下面信息,这个用于strapi的官方信息统计。可见详细说明,所以这里需要将
uuid
删除掉。"strapi": {
"uuid": "1d6ca21f-47e3-45f0-accc-fe80f1234d93"
},
2、插件安装后会自动启用,所以需在config下新建一个
plugins.ts
文件,然后对插件启停进行控制,包含在这里修改插件配置,以便覆盖插件默认配置。请见详细说明// ./config/plugins.ts
module.exports = ({ env }) => ({
// 插件@notum-cz/strapi-plugin-content-versioning
'content-versioning': {
enabled: false,
},
// 插件@strapi/plugin-documentation
documentation: {
enabled: true,
config: {
'x-strapi-config': {
path: '/documentation', // Change this line to change to url of the doc
plugins: ['upload'],
},
},
},
})
yarn add @notum-cz/strapi-plugin-content-versioning
CMS做内容版本控制是很有必要的,然后测试了这个插件,其原理是在新建的类型集合表中新增字段
vuid、version_number、is_visible_in_list_view
、表格tests_versions_links
,其关键点是vuid
字段,在页面上也有点投机取巧的处理。所以如果是Strapi官方默认支持版本控制是最好的,这样子内容管理才能做得更好。
4、swagger文档插件@strapi/plugin-documentation
yarn add @strapi/plugin-documentation
前面提到对
/config/api.ts
的设置后,再加上document插件,这时就可对外提供在线版接口http://localhost:1337/cms/documentation/v1.0.0 。1)但会发现上述页面的css、js等资源404,比如http://localhost:1337/cms/plugins/documentation/swagger-ui.css 404,但http://localhost:1337/plugins/documentation/swagger-ui.css 200,经分析需要修改documentation/server/middlewares/documentation.js的内容
const path = require('path');
const koaStatic = require('koa-static');
const swaggerUi = require('swagger-ui-dist');
module.exports = async ({ strapi }) => {
strapi.server.routes([
{
method: 'GET',
// 【笔者注】官方源内容
// path: '/plugins/documentation/(.*)',
// 【笔者注】新内容
path: strapi.config.get('server.url', '') + '/plugins/documentation/(.*)',
async handler(ctx, next) {
ctx.url = path.basename(ctx.url);
return koaStatic(swaggerUi.getAbsoluteFSPath(), {
maxage: 86400000,
defer: true,
})(ctx, next);
},
config: {
auth: false,
},
},
]);
};
附上documentation的插件设置
// config/plugins.ts
module.exports = ({ env }) => ({
documentation: {
enabled: true,
config: {
'x-strapi-config': {
// 文档的访问子路径
path: '/documentation',
// 去掉'users-permissions',只保留'upload'
plugins: ['upload'],
},
},
},
})
2)解决了资源404后,浏览器控制台报错
Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self'". Either the 'unsafe-inline' keyword,
经分析这是CSP(Content security policy)机制导致的,Strapi Issue里有提到修改方法,但我喜欢简单的,直接关闭CSP
export default [
// 'strapi::security',
{
name: 'strapi::security',
config: {
// 关闭CSP
contentSecurityPolicy: false,
},
},
// ...
]
其他
附package.json中的脚本
"cp": "npm run cp1 && npm run cp2",
"cp1": "cp script/admin-api.js script/content-api.js node_modules/@strapi/strapi/lib/services/server/",
"cp2": "cp script/documentation.js node_modules/@strapi/plugin-documentation/server/middlewares/",
参考资料: