在Angular 4中手动注入Http

时间:2017-07-20 02:17:15

标签: angular

我想手动引导Angular 4应用程序(使用CLI创建)。 在main.ts我这样做:

const injector = ReflectiveInjector.resolveAndCreate([
  Http,
  BrowserXhr,
  {provide: RequestOptions, useClass: BaseRequestOptions},
  {provide: ResponseOptions, useClass: BaseResponseOptions},
  {provide: ConnectionBackend, useClass: XHRBackend},
  {provide: XSRFStrategy, useFactory: () => new CookieXSRFStrategy()},
]);
const http = injector.get(Http);

http.get('assets/configs/configuration.json')
  .map((res: Response) => {
    return res.json();
  }).subscribe((config: Configuration) => {
  configuration = config;
  console.log(JSON.stringify(configuration));
  platformBrowserDynamic().bootstrapModule(AppModule);
});

我似乎得到了一个有效的Http实例但是当我使用它时(http.get)我得到了这个错误:

Uncaught TypeError: Cannot read property 'getCookie' of null
    at CookieXSRFStrategy.webpackJsonp.../../../http/@angular/http.es5.js.CookieXSRFStrategy.configureRequest (vendor.bundle.js:141626)

我的http对象如下所示: enter image description here

4 个答案:

答案 0 :(得分:5)

您可以在Angular开始使用HttpClient之前使用ReflectiveInjector服务:

import { ReflectiveInjector } from '@angular/core';
import { HttpClient, HttpClientModule } from '@angular/common/http';
const injector = ReflectiveInjector.resolveAndCreate(getAnnotations(HttpClientModule)[0].providers);

const http = injector.get(HttpClient);
http.get('/posts/1').subscribe((r) => {
  ConfigurationService.configuration = <Configuration>JSON.parse(config);
  platformBrowserDynamic().bootstrapModule(AppModule);
});

这一行:

getAnnotations(HttpClientModule).providers

引用HttpClientModule上注册的所有提供商,因此您无需手动指定这些提供商。 This answer详细解释了getAnnotations函数。

我所展示的方法是&#34;有点&#34;类似于您将HttpClientModule导入AppModule时所执行的操作:

@NgModule({
    imports: [HttpClientModule, ...],
})
export class AppModule {}

有关详细信息,请参阅this plunker

答案 1 :(得分:3)

作为另一种方法,您可以使用本机浏览器fetch api。所以你不必处理角度http等等

我就是这样做的:

fetch(configUrl, { method: 'get' })
.then((response) => {
  response.json()
    .then((data: any) => {
      if (environment.production) {
        enableProdMode();
      };
      platformBrowserDynamic([{ provide: AppSettings, useValue: new AppSettings(data.config) }]).bootstrapModule(AppModule);
    });
});

但请记住,fetch并没有在old browsers中得到太多的爱,因此您需要使用npm install whatwg-fetch --save import 'whatwg-fetch'然后polyfills.ts对其进行多边处理。如果您想支持旧版浏览器,请在WITH cte_a AS ( SELECT col ,substring(col FROM '%#"Campaign#"%' FOR '#') AS Campaign ,substring(col FROM '%#"Q[1234]#"%' FOR '#') AS QTR ,substring(col FROM '%#"20[0-9][0-9]#"%' FOR '#') AS YEAR FROM table_a ) ,cte_b AS ( SELECT col ,substring(col FROM '%#"Campaign#"%' FOR '#') AS Campaign ,substring(col FROM '%#"Q[1234]#"%' FOR '#') AS QTR ,substring(col FROM '%#"20[0-9][0-9]#"%' FOR '#') AS YEAR FROM table_b ) SELECT * FROM cte_a INNER JOIN cte_b ON ( cte_a.Campaign = cte_b.Campaign AND cte_a.qTR = cte_b.QTR AND cte_a.YEAR = cte_b.YEAR ) 中填写。

<强>更新 是的,您可以使用whatwg-fetch但是您获得的浏览器支持与XMLHttpRequest相同,只是fetch的现代替代品。

答案 2 :(得分:2)

原来的答案可能之前有效,但在Angular 5中我无法使用它,函数getAnnotations没有定义。然而,这对我有用:

import { ReflectiveInjector } from '@angular/core';
import {
  HttpClient,
  XhrFactory,
  HttpHandler,
  HttpXhrBackend,
  HttpBackend
} from '@angular/common/http';

// https://github.com/angular/angular/blob/master/packages/common/http/src/xhr.ts#L45
export class BrowserXhr implements XhrFactory {
  build(): any { return <any>(new XMLHttpRequest()); }
}

const injector = ReflectiveInjector.resolveAndCreate([
  HttpClient,
  HttpXhrBackend,
  { provide: HttpBackend, useExisting: HttpXhrBackend },
  { provide: HttpHandler, useExisting: HttpBackend },
  { provide: XhrFactory, useClass: BrowserXhr},
]);

const http: HttpClient = injector.get(HttpClient);

http.get('/url').subscribe((response) => {
  console.log(response);
});

答案 3 :(得分:1)

谢谢,Kuncevic。我已经提出了这个解决方案,它运行良好:

function httpGetAsync(theUrl, callback) {
  const xmlHttp = new XMLHttpRequest();

  xmlHttp.onreadystatechange = function() {
    if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
      callback(xmlHttp.responseText);
    }
  }

  xmlHttp.open('GET', theUrl, true); // true for asynchronous
  xmlHttp.send(null);
}

httpGetAsync('assets/configs/configuration.json', (config: string) => {
  ConfigurationService.configuration = <Configuration>JSON.parse(config);
  platformBrowserDynamic().bootstrapModule(AppModule);
});