Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/90.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在iframe/object标记内运行时更新初始路由器url_Javascript_Html_Node.js_Express_Vue.js - Fatal编程技术网

Javascript 在iframe/object标记内运行时更新初始路由器url

Javascript 在iframe/object标记内运行时更新初始路由器url,javascript,html,node.js,express,vue.js,Javascript,Html,Node.js,Express,Vue.js,我目前正在容器/主Vue应用程序的对象标记(iframe也可以工作)内呈现Vue应用程序。首先,我设置了一个文件服务器,为该容器或请求的子应用提供服务,以便在div中呈现 为了简单起见,我将只显示Node/Express服务器所需的路由 // serve the sub-app on demand router.get('/subApps/:appName', function(req, res) { res.sendFile(path.resolve(__dirname, `../ap

我目前正在容器/主Vue应用程序的对象标记(iframe也可以工作)内呈现Vue应用程序。首先,我设置了一个文件服务器,为该容器或请求的子应用提供服务,以便在div中呈现

为了简单起见,我将只显示Node/Express服务器所需的路由

// serve the sub-app on demand
router.get('/subApps/:appName', function(req, res) {
    res.sendFile(path.resolve(__dirname, `../apps/${req.params.appName}/index.html`);
});

// always render the app container if no sub-app was requested
router.get('*', function(req, res) {
    res.sendFile(path.resolve(__dirname, '../base/index.html'));
});
My app container/master Vue app位于
/apps/:appName
上呈现的视图文件中,请求该子应用并将其包装到对象标记中

  document.getElementById("customAppContainer").innerHTML = `<object style="width: 100%; height:100%;" data="http://localhost:3000/subApps/${appKey}"></object>`;
我为什么要这样做?主应用程序的App.vue应将子应用程序路由附加到浏览器url。通过这种方法,可以在子应用程序内导航时更新浏览器url。我通过将子应用程序url存储到本地存储并在主应用程序端侦听本地存储更改来实现这一点。因此,App.vue文件使用以下代码

<script>
export default {
  created() {
    window.addEventListener("storage", () => {
      const fullRoute = this.$router.currentRoute.fullPath;
      const routeSegments = fullRoute.split("/");
      const appsIndex = routeSegments.indexOf("apps");
      const newBaseUrlSegments = routeSegments.slice(0, appsIndex + 2);
      const newBaseUrl = newBaseUrlSegments.join("/");
      const subAppRoute = localStorage.subAppRouteUpdate;
      const updatedUrl = newBaseUrl.concat(subAppRoute);
      history.replaceState(null, null, updatedUrl);
    });
  }
};
</script>
if (window.location !== window.parent.location) {
    const browserUrl = top.location.href;
    history.replaceState(null, null, browserUrl);
}

router.afterEach((to, from) => {
    console.log({ urlToAppend: to.path });
    localStorage.subAppRouteUpdate = to.path;
});
replaceState函数将IFrame url从
/subApps/app one
更新为正确的浏览器url
/apps/app one
。不幸的是,这将触发afterEach事件和
to。path
会导致
/apps/app one
,尽管它应该是
/

如果url是
/apps/app one/users/create
,那么每个事件之后都会触发
/users/create

但是我没有弄清楚如何修复这个第一次触发的事件。

这可能是一个有点黑客的解决方案,但对我来说很有效。只要检查当前url路径是否不等于to.path,以防事件触发两次

router.afterEach((to, from) => {
    console.log({ urlToAppend: to.path });
    if (router.currentRoute.path !== to.path) {
        localStorage.subAppRouteUpdate = to.path;
    }
});
更新

在存储事件侦听器中的
base/src/App.vue
中,在将子路由连接到基本路由之前,不检查可能的重复项。这个补丁应该会有帮助

window.addEventListener(“存储”),()=>{
const fullRoute=此。$router.currentRoute.fullPath;
const routeSegments=完整路由分割(“/”);
const appsIndex=routeSegments.indexOf(“应用”);
const newBaseUrlSegments=routeSegments.slice(0,appsIndex+2);
const newBaseUrl=newBaseUrlSegments.join(“/”);
const subAppRoute=localStorage.subAppRouteUpdate;
if(子路径开始与(newBaseUrl)){
replaceState(null,null,newBaseUrl);
}否则{
const updatedUrl=newBaseUrl.concat(子路径);
replaceState(null,null,updateUrl);
}
});
和<代码>路由器。每次<代码>后,应如下所示导航到app one路由器中定义的子例程:

router.afterEach((to, from) => {
        const newPath = '/' + to.path.split('/').pop();
        const matchingRoutes = router.options.routes.filter(r => r.path === newPath);
        const isPathInRoutes = matchingRoutes.length > 0;
        if (router.currentRoute.path !== newPath && isPathInRoutes) {
            router.push(newPath);
            localStorage.subAppRouteUpdate = newPath;
        } else {
            localStorage.subAppRouteUpdate = to.path;
        }
});
如果您希望在用户转到
http://localhost:3000/apps/app-一个
您可以检查输入url的最后一部分是否等于子应用程序基本路由(
/app one
),以及它是否导航到默认页面路由(
/
):

router.afterEach((to,from)=>{
让newPath='/'+到.path.split('/').pop();
const matchingRoutes=router.options.routes.filter(r=>r.path==newPath);
const isPathInRoutes=matchingRoutes.length>0;
if(newPath==router.history.base | |!isPathInRoutes){
新路径='/';
}
if(router.currentRoute.path!==newPath){
路由器推送(newPath);
localStorage.subAppRouteUpdate=newPath;
}否则{
localStorage.subAppRouteUpdate=to.path;
}
});

因此,如果您导航到
应用程序1-第2页
浏览器url仍然是
http://localhost:3000/apps/app-一个
但我希望
http://localhost:3000/apps/app-一/二
你能检查一下我更新的答案是否按预期工作吗?是的,你几乎做到了!:)我遇到的最后一个问题是调用此url
http://localhost:3000/apps/app-一个
子应用程序不会呈现视图一个。
http://localhost:3000/apps/app-一个/两个
我希望它能呈现两个。:/@ktad我奖赏你:)页面的呈现仍然丢失,但我也更新了我的答案,因此当用户导航到
http://localhost:3000/apps/app-一个
router.afterEach((to, from) => {
        const newPath = '/' + to.path.split('/').pop();
        const matchingRoutes = router.options.routes.filter(r => r.path === newPath);
        const isPathInRoutes = matchingRoutes.length > 0;
        if (router.currentRoute.path !== newPath && isPathInRoutes) {
            router.push(newPath);
            localStorage.subAppRouteUpdate = newPath;
        } else {
            localStorage.subAppRouteUpdate = to.path;
        }
});