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
相关产品推荐
相关产品推荐

