2017-02-11 01:00:27 +00:00
|
|
|
/**
|
|
|
|
|
* @license
|
2020-05-19 19:08:49 +00:00
|
|
|
* Copyright Google LLC All Rights Reserved.
|
2017-02-11 01:00:27 +00:00
|
|
|
*
|
|
|
|
|
* Use of this source code is governed by an MIT-style license that can be
|
2024-09-20 15:23:15 +00:00
|
|
|
* found in the LICENSE file at https://angular.dev/license
|
2017-02-11 01:00:27 +00:00
|
|
|
*/
|
2019-03-20 00:41:12 +00:00
|
|
|
|
2023-10-23 12:58:03 +00:00
|
|
|
import {PlatformLocation, XhrFactory} from '@angular/common';
|
2024-04-19 16:13:59 +00:00
|
|
|
import {
|
|
|
|
|
HttpEvent,
|
|
|
|
|
HttpHandlerFn,
|
|
|
|
|
HttpRequest,
|
|
|
|
|
ɵHTTP_ROOT_INTERCEPTOR_FNS as HTTP_ROOT_INTERCEPTOR_FNS,
|
|
|
|
|
} from '@angular/common/http';
|
2023-10-23 12:58:03 +00:00
|
|
|
import {inject, Injectable, Provider} from '@angular/core';
|
|
|
|
|
import {Observable} from 'rxjs';
|
2021-09-21 14:20:45 +00:00
|
|
|
|
2017-02-11 01:00:27 +00:00
|
|
|
@Injectable()
|
2019-03-20 00:41:12 +00:00
|
|
|
export class ServerXhr implements XhrFactory {
|
2024-04-19 16:13:59 +00:00
|
|
|
private xhrImpl: typeof import('xhr2') | undefined;
|
2023-05-01 21:31:09 +00:00
|
|
|
|
|
|
|
|
// The `xhr2` dependency has a side-effect of accessing and modifying a
|
|
|
|
|
// global scope. Loading `xhr2` dynamically allows us to delay the loading
|
|
|
|
|
// and start the process once the global scope is established by the underlying
|
|
|
|
|
// server platform (via shims, etc).
|
|
|
|
|
private async ɵloadImpl(): Promise<void> {
|
|
|
|
|
if (!this.xhrImpl) {
|
|
|
|
|
const {default: xhr} = await import('xhr2');
|
|
|
|
|
this.xhrImpl = xhr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-13 23:40:21 +00:00
|
|
|
build(): XMLHttpRequest {
|
2023-05-01 21:31:09 +00:00
|
|
|
const impl = this.xhrImpl;
|
|
|
|
|
if (!impl) {
|
|
|
|
|
throw new Error('Unexpected state in ServerXhr: XHR implementation is not loaded.');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new impl.XMLHttpRequest();
|
2020-04-13 23:40:21 +00:00
|
|
|
}
|
2017-02-11 01:00:27 +00:00
|
|
|
}
|
|
|
|
|
|
2023-10-23 12:58:03 +00:00
|
|
|
function relativeUrlsTransformerInterceptorFn(
|
2024-04-19 16:13:59 +00:00
|
|
|
request: HttpRequest<unknown>,
|
|
|
|
|
next: HttpHandlerFn,
|
|
|
|
|
): Observable<HttpEvent<unknown>> {
|
2023-10-23 12:58:03 +00:00
|
|
|
const platformLocation = inject(PlatformLocation);
|
|
|
|
|
const {href, protocol, hostname, port} = platformLocation;
|
|
|
|
|
if (!protocol.startsWith('http')) {
|
|
|
|
|
return next(request);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let urlPrefix = `${protocol}//${hostname}`;
|
|
|
|
|
if (port) {
|
|
|
|
|
urlPrefix += `:${port}`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const baseHref = platformLocation.getBaseHrefFromDOM() || href;
|
|
|
|
|
const baseUrl = new URL(baseHref, urlPrefix);
|
|
|
|
|
const newUrl = new URL(request.url, baseUrl).toString();
|
|
|
|
|
|
|
|
|
|
return next(request.clone({url: newUrl}));
|
|
|
|
|
}
|
2017-03-23 00:13:24 +00:00
|
|
|
|
2017-02-11 01:00:27 +00:00
|
|
|
export const SERVER_HTTP_PROVIDERS: Provider[] = [
|
2023-03-23 11:37:42 +00:00
|
|
|
{provide: XhrFactory, useClass: ServerXhr},
|
2023-10-23 12:58:03 +00:00
|
|
|
{
|
|
|
|
|
provide: HTTP_ROOT_INTERCEPTOR_FNS,
|
|
|
|
|
useValue: relativeUrlsTransformerInterceptorFn,
|
|
|
|
|
multi: true,
|
|
|
|
|
},
|
2017-02-11 01:00:27 +00:00
|
|
|
];
|