You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel9中L5-Swagger自定义OperationsLayout布局的调用问题

Laravel 9 + L5-Swagger 自定义布局跨脚本访问问题解决

问题描述

在Laravel 9中使用DarkaOnLine/L5-Swagger包时,自定义OperationsLayout布局后,在第二个<script>标签的SwaggerUIBundle配置中调用该布局,始终提示“布局不存在”。尝试过用localStorage共享变量但未成功,相关代码如下:

<body>
<div id="swagger-ui"></div>

<script src="{{ l5_swagger_asset($documentation, 'swagger-ui-bundle.js') }}"></script>
<script src="{{ l5_swagger_asset($documentation, 'swagger-ui-standalone-preset.js') }}"></script>

<!-- Load React. -->
<!-- Note: when deploying, replace "development.js" with "production.min.js". -->
<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>

<script type="text/babel">
    import React from "react"

    // Create the layout component
    class OperationsLayout extends React.Component {
        render() {
            const {
                getComponent
            } = this.props
            const Operations = getComponent("operations", true)
            return (
                <div>
                    <Operations />
                </div>
            )
        }
    }

    // Create the plugin that provides our layout component
    const OperationsLayoutPlugin = () => {
        return {
            components: {
                OperationsLayout: OperationsLayout
            }
        }
    }

    // Provide the plugin to Swagger-UI, and select OperationsLayout
    // as the layout for Swagger-UI
    SwaggerUIBundle({
        url: "{!! $urlToDocs !!}",
        plugins: [ OperationsLayoutPlugin ],
        layout: "OperationsLayout"
    })
</script>

<script>
    window.onload = function() {
        // Build a system
        const ui = SwaggerUIBundle({
            dom_id: '#swagger-ui',
            url: "{!! $urlToDocs !!}",
            operationsSorter: {!! isset($operationsSorter) ? '"' . $operationsSorter . '"' : 'null' !!},
            configUrl: {!! isset($configUrl) ? '"' . $configUrl . '"' : 'null' !!},
            validatorUrl: {!! isset($validatorUrl) ? '"' . $validatorUrl . '"' : 'null' !!},
            oauth2RedirectUrl: "{{ route('l5-swagger.'.$documentation.'.oauth2_callback', [], $useAbsolutePath) }}",

            requestInterceptor: function(request) {
                request.headers['X-CSRF-TOKEN'] = '{{ csrf_token() }}';
                return request;
            },

            presets: [
                SwaggerUIBundle.presets.apis,
                SwaggerUIStandalonePreset
            ],

            plugins: [
                SwaggerUIBundle.plugins.DownloadUrl
            ],

            layout: "StandaloneLayout",
            docExpansion : "{!! config('l5-swagger.defaults.ui.display.doc_expansion', 'none') !!}",
            deepLinking: true,
            filter: {!! config('l5-swagger.defaults.ui.display.filter') ? 'true' : 'false' !!},
            persistAuthorization: "{!! config('l5-swagger.defaults.ui.authorization.persist_authorization') ? 'true' : 'false' !!}",

        })

        window.ui = ui
    }
</script>
</body>

解决方案

问题根源是不同<script>标签的作用域隔离,且代码中重复初始化了两次SwaggerUI。按以下步骤修改:

  • 将自定义插件挂载到全局
    在type="text/babel"脚本中删除多余的SwaggerUIBundle初始化代码,并将自定义插件挂载到window对象,让第二个脚本能访问:

    <script type="text/babel">
        // 移除import React from "react"(CDN加载的React是全局对象)
        class OperationsLayout extends React.Component {
            render() {
                const { getComponent } = this.props;
                const Operations = getComponent("operations", true);
                return (
                    <div>
                        <Operations />
                    </div>
                );
            }
        }
    
        const OperationsLayoutPlugin = () => {
            return {
                components: {
                    OperationsLayout: OperationsLayout
                }
            };
        };
    
        // 挂载到全局window
        window.OperationsLayoutPlugin = OperationsLayoutPlugin;
    </script>
    
  • 合并SwaggerUI配置
    在第二个<script>的SwaggerUIBundle配置中,添加自定义插件并修改布局参数:

    plugins: [
        SwaggerUIBundle.plugins.DownloadUrl,
        window.OperationsLayoutPlugin // 引入自定义插件
    ],
    layout: "OperationsLayout", // 替换原StandaloneLayout为自定义布局
    
  • 确保执行顺序
    保证type="text/babel"脚本在第二个<script>之前加载执行,确保全局变量已被定义。

内容的提问来源于stack exchange,提问作者Coding

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 22:40:28