This reverts commit 420d1c35f5
.
PR Close #37547
This commit is contained in:
@ -10,12 +10,13 @@
|
|||||||
const xhr2: any = require('xhr2');
|
const xhr2: any = require('xhr2');
|
||||||
|
|
||||||
import {Injectable, Injector, Provider} from '@angular/core';
|
import {Injectable, Injector, Provider} from '@angular/core';
|
||||||
import {PlatformLocation} from '@angular/common';
|
import {DOCUMENT} from '@angular/common';
|
||||||
import {HttpEvent, HttpRequest, HttpHandler, HttpBackend, XhrFactory, ɵHttpInterceptingHandler as HttpInterceptingHandler} from '@angular/common/http';
|
import {HttpEvent, HttpRequest, HttpHandler, HttpBackend, XhrFactory, ɵHttpInterceptingHandler as HttpInterceptingHandler} from '@angular/common/http';
|
||||||
import {Observable, Observer, Subscription} from 'rxjs';
|
import {Observable, Observer, Subscription} from 'rxjs';
|
||||||
|
|
||||||
// @see https://www.w3.org/Protocols/HTTP/1.1/draft-ietf-http-v11-spec-01#URI-syntax
|
// @see https://www.w3.org/Protocols/HTTP/1.1/draft-ietf-http-v11-spec-01#URI-syntax
|
||||||
const isAbsoluteUrl = /^[a-zA-Z\-\+.]+:\/\//;
|
const isAbsoluteUrl = /^[a-zA-Z\-\+.]+:\/\//;
|
||||||
|
const FORWARD_SLASH = '/';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ServerXhr implements XhrFactory {
|
export class ServerXhr implements XhrFactory {
|
||||||
@ -104,18 +105,20 @@ export abstract class ZoneMacroTaskWrapper<S, R> {
|
|||||||
|
|
||||||
export class ZoneClientBackend extends
|
export class ZoneClientBackend extends
|
||||||
ZoneMacroTaskWrapper<HttpRequest<any>, HttpEvent<any>> implements HttpBackend {
|
ZoneMacroTaskWrapper<HttpRequest<any>, HttpEvent<any>> implements HttpBackend {
|
||||||
constructor(private backend: HttpBackend, private platformLocation: PlatformLocation) {
|
constructor(private backend: HttpBackend, private doc: Document) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
handle(request: HttpRequest<any>): Observable<HttpEvent<any>> {
|
handle(request: HttpRequest<any>): Observable<HttpEvent<any>> {
|
||||||
const {href, protocol, hostname} = this.platformLocation;
|
const href = this.doc.location.href;
|
||||||
if (!isAbsoluteUrl.test(request.url) && href !== '/') {
|
if (!isAbsoluteUrl.test(request.url) && href) {
|
||||||
const baseHref = this.platformLocation.getBaseHrefFromDOM() || href;
|
const urlParts = Array.from(request.url);
|
||||||
const urlPrefix = `${protocol}//${hostname}`;
|
if (request.url[0] === FORWARD_SLASH && href[href.length - 1] === FORWARD_SLASH) {
|
||||||
const baseUrl = new URL(baseHref, urlPrefix);
|
urlParts.shift();
|
||||||
const url = new URL(request.url, baseUrl);
|
} else if (request.url[0] !== FORWARD_SLASH && href[href.length - 1] !== FORWARD_SLASH) {
|
||||||
return this.wrap(request.clone({url: url.toString()}));
|
urlParts.splice(0, 0, FORWARD_SLASH);
|
||||||
|
}
|
||||||
|
return this.wrap(request.clone({url: href + urlParts.join('')}));
|
||||||
}
|
}
|
||||||
return this.wrap(request);
|
return this.wrap(request);
|
||||||
}
|
}
|
||||||
@ -126,15 +129,15 @@ export class ZoneClientBackend extends
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function zoneWrappedInterceptingHandler(
|
export function zoneWrappedInterceptingHandler(
|
||||||
backend: HttpBackend, injector: Injector, platformLocation: PlatformLocation) {
|
backend: HttpBackend, injector: Injector, doc: Document) {
|
||||||
const realBackend: HttpBackend = new HttpInterceptingHandler(backend, injector);
|
const realBackend: HttpBackend = new HttpInterceptingHandler(backend, injector);
|
||||||
return new ZoneClientBackend(realBackend, platformLocation);
|
return new ZoneClientBackend(realBackend, doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SERVER_HTTP_PROVIDERS: Provider[] = [
|
export const SERVER_HTTP_PROVIDERS: Provider[] = [
|
||||||
{provide: XhrFactory, useClass: ServerXhr}, {
|
{provide: XhrFactory, useClass: ServerXhr}, {
|
||||||
provide: HttpHandler,
|
provide: HttpHandler,
|
||||||
useFactory: zoneWrappedInterceptingHandler,
|
useFactory: zoneWrappedInterceptingHandler,
|
||||||
deps: [HttpBackend, Injector, PlatformLocation]
|
deps: [HttpBackend, Injector, DOCUMENT]
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
@ -51,7 +51,6 @@ export class ServerPlatformLocation implements PlatformLocation {
|
|||||||
this.pathname = parsedUrl.pathname;
|
this.pathname = parsedUrl.pathname;
|
||||||
this.search = parsedUrl.search;
|
this.search = parsedUrl.search;
|
||||||
this.hash = parsedUrl.hash;
|
this.hash = parsedUrl.hash;
|
||||||
this.href = _doc.location.href;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -841,58 +841,6 @@ describe('platform-server integration', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can make relative HttpClient requests no slashes longer url', async () => {
|
|
||||||
const platform = platformDynamicServer([{
|
|
||||||
provide: INITIAL_CONFIG,
|
|
||||||
useValue: {document: '<app></app>', url: 'http://localhost/path/page'}
|
|
||||||
}]);
|
|
||||||
const ref = await platform.bootstrapModule(HttpClientExampleModule);
|
|
||||||
const mock = ref.injector.get(HttpTestingController) as HttpTestingController;
|
|
||||||
const http = ref.injector.get(HttpClient);
|
|
||||||
ref.injector.get(NgZone).run(() => {
|
|
||||||
http.get<string>('testing').subscribe((body: string) => {
|
|
||||||
NgZone.assertInAngularZone();
|
|
||||||
expect(body).toEqual('success!');
|
|
||||||
});
|
|
||||||
mock.expectOne('http://localhost/path/testing').flush('success!');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can make relative HttpClient requests slashes longer url', async () => {
|
|
||||||
const platform = platformDynamicServer([{
|
|
||||||
provide: INITIAL_CONFIG,
|
|
||||||
useValue: {document: '<app></app>', url: 'http://localhost/path/page'}
|
|
||||||
}]);
|
|
||||||
const ref = await platform.bootstrapModule(HttpClientExampleModule);
|
|
||||||
const mock = ref.injector.get(HttpTestingController) as HttpTestingController;
|
|
||||||
const http = ref.injector.get(HttpClient);
|
|
||||||
ref.injector.get(NgZone).run(() => {
|
|
||||||
http.get<string>('/testing').subscribe((body: string) => {
|
|
||||||
NgZone.assertInAngularZone();
|
|
||||||
expect(body).toEqual('success!');
|
|
||||||
});
|
|
||||||
mock.expectOne('http://localhost/testing').flush('success!');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can make relative HttpClient requests slashes longer url with base href', async () => {
|
|
||||||
const platform = platformDynamicServer([{
|
|
||||||
provide: INITIAL_CONFIG,
|
|
||||||
useValue:
|
|
||||||
{document: '<base href="http://other"><app></app>', url: 'http://localhost/path/page'}
|
|
||||||
}]);
|
|
||||||
const ref = await platform.bootstrapModule(HttpClientExampleModule);
|
|
||||||
const mock = ref.injector.get(HttpTestingController) as HttpTestingController;
|
|
||||||
const http = ref.injector.get(HttpClient);
|
|
||||||
ref.injector.get(NgZone).run(() => {
|
|
||||||
http.get<string>('/testing').subscribe((body: string) => {
|
|
||||||
NgZone.assertInAngularZone();
|
|
||||||
expect(body).toEqual('success!');
|
|
||||||
});
|
|
||||||
mock.expectOne('http://other/testing').flush('success!');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('requests are macrotasks', async(() => {
|
it('requests are macrotasks', async(() => {
|
||||||
const platform = platformDynamicServer(
|
const platform = platformDynamicServer(
|
||||||
[{provide: INITIAL_CONFIG, useValue: {document: '<app></app>'}}]);
|
[{provide: INITIAL_CONFIG, useValue: {document: '<app></app>'}}]);
|
||||||
|
Reference in New Issue
Block a user