欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue3使用iframe嵌入ureport2設計器,解決預覽時NullPointerException異常問題

 更新時間:2023年10月11日 09:10:06   作者:slxz001  
這篇文章主要介紹了vue3使用iframe嵌入ureport2設計器,解決預覽時NullPointerException異常問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

1. 后端準備

關(guān)于SpringBoot集成UReport2的文章網(wǎng)絡上有很多,這里只記錄2個容易踩坑的地方:

配置類

很多文章在寫后端集成的時候,都在配置類中使用@Bean注解創(chuàng)建ServletRegistrationBeanUReportPropertyPlaceholderConfigurer對象。

但在實際使用過程中發(fā)現(xiàn),如果要將SpringBoot創(chuàng)建的DataSource作為UReport2的內(nèi)置數(shù)據(jù)源,則需要將@Bean注解放到配置類以外的地方,否則DataSource無法注入。

@Configuration
public class ReportBean {
    //添加 report 的servlet
    @Bean
    public ServletRegistrationBean<Servlet> ureport2Servlet() {
        return new ServletRegistrationBean<>(new UReportServlet(), "/ureport/*");
    }
    //這一步省略了創(chuàng)建配置文件
    @Bean
    public UReportPropertyPlaceholderConfigurer UReportPropertyPlaceholderConfigurer() {
        UReportPropertyPlaceholderConfigurer propertyConfigurer = new UReportPropertyPlaceholderConfigurer();
        propertyConfigurer.setIgnoreUnresolvablePlaceholders(true);
        ClassPathResource pathResource = new ClassPathResource("config/config.properties");
        propertyConfigurer.setLocation(pathResource);
        return propertyConfigurer;
    }
}
@Configuration
//導入ureport-console-context.xml文件
@ImportResource("classpath:config/context.xml")
@Slf4j
public class ReportConfig implements BuildinDatasource {
    @Autowired
    private DataSource dataSource;
    /**
     * 數(shù)據(jù)源名稱
     **/
    @Override
    public String name() {
        return "ReportSource";
    }
    /**
     * 獲取連接
     **/
    @Override
    public Connection getConnection() {
        try {
            return dataSource.getConnection();
        } catch (SQLException e) {
            log.error("Ureport 數(shù)據(jù)源 獲取連接失敗!");
            e.printStackTrace();
        }
        return null;
    }
}

report.fileStoreDir配置

在ureport的配置文件中,ureport.fileStoreDir表示報表的xml文件在磁盤上的存儲目錄。

配置完這個目錄,必須手動創(chuàng)建,否則在設計器中保存報表時會報錯。

2. 前端嵌入

假設后端集成完畢后,報表設計器的訪問路徑在http://localhost:9000/ureport/designer

<template>
	<div v-loading="loading" class="h-full">
		<iframe :src="src" frameborder="no" class="wh-full" scrolling="auto" />
	</div>
</template>
<script setup lang="tsx">
import { ref } from 'vue';
const src = ref<string>('/ureport/designer');
const loading = ref<boolean>(true);
</script>

可以看到,我們沒有直接將iframe的src指向http://localhost:9000/ureport/designer,否則會由于跨域問題而無法顯示。

這里我們配了一個報表設計器的相對路徑,并將“ureport”進行前端代理。

'/ureport': {
	target: envConfig.secondUrl,
    changeOrigin: true,
    rewrite: path => path.replace(new RegExp(`^${envConfig.urlPattern}`), '/ureport')
}

這里我們讓代理攔截前綴為"/ureport"的請求。

由于報表后端路徑也是以"/ureport"開頭,所以rewrite中不需要將"/ureport"刪掉,也可以不寫rewrite。

3. 預覽問題

假設我們的前端工程以8000端口啟動。

將ureport報表設計器嵌入到iframe后,點擊左上角的預覽,瀏覽器將打開一個新的tab頁,其URL地址為http://localhost:8000/ureport/preview?_u=p

其中,參數(shù)_u表示要預覽的報表文件名稱,在預覽時約定文件名為p。此時頁面無法正常打開,只顯示NullPointerException。

經(jīng)過跟蹤ureport2源碼,發(fā)現(xiàn)_u參數(shù)沒有發(fā)送到后端。

4. 問題排查與解決

1.嘗試使用后端端口直接訪問http://localhost:9000/ureport/preview?_u=p發(fā)現(xiàn)可以訪問,但無法預覽。閱讀源碼發(fā)現(xiàn)ureport預覽報表時,報表內(nèi)容隨session傳遞。因此前后端端口不一致時找不到報表內(nèi)容,無法預覽。

2.嘗試新建一個vue頁面,來進行請求轉(zhuǎn)發(fā)發(fā)現(xiàn)行不通。直接轉(zhuǎn)發(fā)到后端依然存在跨域問題,通過前端代理進行轉(zhuǎn)發(fā),參數(shù)還是傳不到后端。

3.使用postman調(diào)用前端地址(注意,調(diào)用8000端口)http://localhost:8000/ureport/preview?_u=p,發(fā)現(xiàn)參數(shù)可以傳遞到后端。

到這一步就比較尷尬了。同一地址,使用postman請求,前端代理可以把URL完整傳遞到后端。使用瀏覽器請求,前端代理不發(fā)送URL參數(shù)到后端。

經(jīng)過比對和測試,發(fā)現(xiàn)瀏覽器發(fā)送請求時,其header頭的Accept內(nèi)容為“text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7”。當使用postman發(fā)送請求時,其header頭的Accept內(nèi)容為“*/*”

跟蹤了代理的rewrite方法,發(fā)現(xiàn)使用瀏覽器訪問時,傳入的path是不帶參數(shù)的。閱讀vite的部分源碼,并結(jié)合查詢到的一些資料,發(fā)現(xiàn)在配置代理時,除了常規(guī)的target、rewrite以外,還可以配置
configure和bypass

源碼如下:

export declare interface ProxyOptions extends HttpProxy.ServerOptions {
    /**
     * rewrite path
     */
    rewrite?: (path: string) => string;
    /**
     * configure the proxy server (e.g. listen to events)
     */
    configure?: (proxy: HttpProxy.Server, options: ProxyOptions) => void;
    /**
     * webpack-dev-server style bypass function
     */
    bypass?: (req: http.IncomingMessage, res: http.ServerResponse, options: ProxyOptions) => void | null | undefined | false | string;
}

可以看到,configure和bypass方法,都可以取得一個req變量,其類型是http.IncomeingMessage

跟蹤req對象,發(fā)現(xiàn)其存在兩個屬性:

  • req.client.originalUrl,其屬性值為/ureport/preview?_u=p
  • req.url,其屬性值為/ureport/preview

到這里,終于有了些許思路。我們最終的目的就是利用前端代理來訪問ureport的預覽界面,只要解決了前端代理的參數(shù)傳遞問題,就可以直接預覽了。

因此,目前的思路就是讓代理直接轉(zhuǎn)發(fā)req.client.originalUrl就好。

因此我們改造一下定義代理的配置語句,增加bypass配置:

'/ureport': {
    target: envConfig.secondUrl,
    changeOrigin: true,
    rewrite: path => path.replace(new RegExp(`^${envConfig.urlPattern}`), '/ureport'),
    bypass: (req, res, proxyOption) => {
      req.url = req.originalUrl;
    }
}

在這里,我們在代理轉(zhuǎn)發(fā)請求之前,將他本來要轉(zhuǎn)發(fā)的地址強行替換為原url地址。

此時請求的參數(shù)可以轉(zhuǎn)發(fā)到后端,預覽頁面成功打開。

5. 總結(jié)

1.雖然在分析過程中,知道了瀏覽器請求和postman請求時,由于Header中的Accept不同導致了不同的結(jié)果,但最終還是沒有精力去找具體是哪段代碼導致了這個差異。換句話說,vite用到的http-proxy組件在不同情況下對URL地址進行了不同的處理,如果有知道原理的大神可以留個言。

2.vue2下沒測出來類似的問題,等有時間要查查vue2前端代理用的組件和vue3有什么不同。

3.nginx的代理可以完美轉(zhuǎn)發(fā)請求,不存在丟參數(shù)的情況。

4.我們最終在bypass中強行修改了代理轉(zhuǎn)發(fā)的url地址,并成功打開了頁面,但這種做法有違http-proxy的設計原理。目前不清楚這種做法會造成什么其他未知后果,不過想來問題不大,因為bypass只對"/ureport"開頭的請求進行了代理,不影響系統(tǒng)的其他請求。

5.這個小問題排查了兩三天,看見很多關(guān)于ureport2集成的文章下面都有人問這個預覽的問題如何解決。所以就臨時整理思路寫了這篇文章,問題排查部分寫的可能比較亂,湊合看吧。以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • vue實現(xiàn)移動端適方案的完整步驟

    vue實現(xiàn)移動端適方案的完整步驟

    現(xiàn)在的手機五花八門,造就了移動端窗口分辨率繁多的局面,在不同分辨率的屏幕下保持與UI圖一致的效果,就成了讓前端不得不頭疼的問題,下面這篇文章主要給大家介紹了vue實現(xiàn)移動端適方案的相關(guān)資料,需要的朋友可以參考下
    2022-10-10
  • vue3 elementplus table合并寫法

    vue3 elementplus table合并寫法

    這篇文章主要介紹了vue3 elementplus table合并寫法,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-06-06
  • 詳解在vue-cli中引用jQuery、bootstrap以及使用sass、less編寫css

    詳解在vue-cli中引用jQuery、bootstrap以及使用sass、less編寫css

    這篇文章主要介紹了詳解在vue-cli中引用jQuery、bootstrap以及使用sass、less編寫css,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • vue v-for循環(huán)出來的數(shù)據(jù)動態(tài)綁定值問題

    vue v-for循環(huán)出來的數(shù)據(jù)動態(tài)綁定值問題

    這篇文章主要介紹了vue v-for循環(huán)出來的數(shù)據(jù)動態(tài)綁定值問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • vue?3.0?vue.config.js文件常用配置方式

    vue?3.0?vue.config.js文件常用配置方式

    這篇文章主要介紹了vue?3.0?vue.config.js文件常用配置方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • 詳解如何在Vue3+TS的項目中使用NProgress進度條

    詳解如何在Vue3+TS的項目中使用NProgress進度條

    本文主要介紹了詳解如何在Vue3+TS的項目中使用NProgress進度條,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-06-06
  • vue bus全局事件中心簡單Demo詳解

    vue bus全局事件中心簡單Demo詳解

    ue-bus 提供了一個全局事件中心,并將其注入每一個組件,你可以像使用內(nèi)置事件流一樣方便的使用全局事件。這篇文章給大家介紹了vue bus全局事件中心簡單Demo,需要的朋友參考下吧
    2018-02-02
  • 使用vue實現(xiàn)點擊按鈕滑出面板的實現(xiàn)代碼

    使用vue實現(xiàn)點擊按鈕滑出面板的實現(xiàn)代碼

    這篇文章主要介紹了使用vue實現(xiàn)點擊按鈕滑出面板的實現(xiàn)代碼,非常不錯,具有參考借鑒價值,需要的朋友參考下
    2017-01-01
  • Vue3+Vant實現(xiàn)簡單的登錄功能

    Vue3+Vant實現(xiàn)簡單的登錄功能

    這篇文章主要為大家詳細介紹了Vue3如何結(jié)合Vant實現(xiàn)簡單的登錄功能,文中的示例代碼講解詳細,有需要的小伙伴可以跟隨小編一起學習一下
    2024-04-04
  • Vue基于iview table展示圖片實現(xiàn)點擊放大

    Vue基于iview table展示圖片實現(xiàn)點擊放大

    這篇文章主要介紹了Vue基于iview table展示圖片實現(xiàn)點擊放大,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-08-08

最新評論