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/adminapp.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
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/",
 

参考资料:

© 刘德华 2020 - 2025