Angular 7:如何获取当前页面的完整URL

6

如何在Angular 7中获取完整的当前URL而不使用window.location.href

例如,假设我的当前URL是http://localhost:8080/p/drinks?q=cold&price=200

如何获取完整的URL而不仅仅是/p/drinks?q=cold&price=200

我尝试过使用this.router.url,但这只给出了/p/drinks?q=cold&price=200而没有完整的主机名。

我不想使用window.location.href的原因是它会导致在ng-toolkit/universal中呈现问题。

我尝试遵循这个解决方案,它似乎与我遇到的问题相同,并进行了更新

如何在Angular2中为服务获取域名

以下是我的代码

windowProvider.js

import { InjectionToken, FactoryProvider } from '@angular/core';

export const WINDOW = new InjectionToken<Window>('window');

const windowProvider: FactoryProvider = {
  provide: WINDOW,
  useFactory: () => window
};

export const WINDOW_PROVIDERS = [
  windowProvider
];

app.module.ts文件中。
@NgModule({
    .......
    providers:[
    .......
    windowProvider
   ]
})

在我的必要页面中:
import {WINDOW as WindowFactory} from '../../factory/windowProvider';
......
 constructor(private router: Router, private helper: Helpers,
             @Inject(WindowFactory) private windowFactory: any,
            ) {
console.warn('HELLO I M WINDOW FACTORY', this.windowFactory.location.hostname);
}

购买此项会在编译时出现错误

./src/app/factory/windowProvider.js的第5行20列出现了意外的令牌(5:20)。您可能需要一个适当的加载器来处理此文件类型。| export const WINDOW = new InjectionToken('window'); |

const windowProvider: FactoryProvider = { | provide: WINDOW, | useFactory: () => window ℹ 「wdm」: Failed to compile.

请问有人可以告诉我如何解决这个问题。谢谢。

我还查阅了以下链接:


1
看看这个是否有帮助 https://dev59.com/VKbja4cB1Zd3GeqPiI1n#47205502 - David
@David,我检查了链接,似乎可能有效,但我无法使其工作。我已经在你的答案上发表了评论,请你看一下。 - user7747472
1个回答

9

通用的服务器端不知道window.location。

另一方面,Express服务器从发送到服务器端的请求中知道URL。

因此,我们需要将来自Express的请求URL注入到Angular中。

server.ts

let template = readFileSync(join(__dirname, '..', 'dist', 'index.html')).toString();

app.engine('html', (_, options, callback) => {
    renderModuleFactory(AppServerModuleNgFactory, {
        document: template,
        url: options.req.url,
        extraProviders: [
            { provide: 'requestUrl', useFactory: () => options.req.url, deps: [] },    // 1. set up the provider for the url
            provideModuleMap(LAZY_MODULE_MAP)
        ]
    }).then(html => {
        callback(null, html);
    });
});

为了在需要时检索它,我们需要进行相应的操作。

url-logger.ts

class UrlLogger {
    constructor(
        private window: Location,
        private injector: Injector,                         // 2. we need the injector to ..
        @Inject(PLATFORM_ID) private platformId: string,
    ) { }

    public log() {
        if (isPlatformServer(this.platformId)) {
            const requestUrl = this.injector.get('requestUrl');    // 3. ..retrieve the injected url
            console.log('server greets you via ' + requestUrl)
        } else {
            console.log('browser says hello from ' + window.location.href)
        }
    } 
}

“template”是一个常量或类似的东西。如果我从Angular核心导入它,那么会抛出错误。 - user7747472
template 是你的模板 index.html 的完整路径:renderModuleFactory() 函数以一个模板 HTML 页面(通常是 index.html)、包含组件的 Angular 模块和一个路由作为输入,以确定显示哪些组件。 参见 angular 文档。我已经相应地编辑了答案。 - lolcatzftw

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接