如何使用proxy.conf.json将数据返回到Angular应用程序?

时间:2018-03-23 06:36:33

标签: json angular webpack proxy

我正在使用proxy.conf.json来开发我的Angular应用程序。

但是,对于一些端点,我想在调用时返回一个JSON对象。目前,我的proxy.conf文件重定向到本地运行的后端,后端返回这些JSON。但是,我宁愿不运行后端服务器,只需从proxy.conf.json返回JSON。

这有可能吗?

2 个答案:

答案 0 :(得分:5)

可以使用proxy.conf.js代替proxy.conf.json。然后,您可以指定旁路功能,您可以在其中直接返回响应。代理的angular-cli documentation中提到了这一点,但它没有提供很多细节。这是一个示例proxy.conf.js文件。

const PROXY_CONFIG = {
  '/api': {
    'target': 'http://localhost:5000',
    'bypass': function (req, res, proxyOptions) {
      switch (req.url) {
        case '/api/json1':
          const objectToReturn1 = {
            value1: 1,
            value2: 'value2',
            value3: 'value3'
          };
          res.end(JSON.stringify(objectToReturn1));
          return true;
        case '/api/json2':
          const objectToReturn2 = {
            value1: 2,
            value2: 'value3',
            value3: 'value4'
          };
          res.end(JSON.stringify(objectToReturn2));
          return true;
      }
    }
  }
}

module.exports = PROXY_CONFIG;

您需要重新检查旁路功能中的网址,因为它会针对所有/api请求进行调用,然后您只需直接返回您想要的响应,其他人仍将被重定向到目标地址。您返回true以告知代理请求已完成。

确保在运行ng serve --proxy-config proxy.conf.js时指定正确的文件。

答案 1 :(得分:1)

要从proxy.config.conf返回JSON,似乎没有一种简单的方法可以做到。

一种方法是在baseApiUrl文件中设置environment.ts,将urlSuffix设置为.json。然后,所有API调用都必须是这样的:enviroment.baseApiUrl + uri + environment.urlSuffix。然后在environment.prod.ts中,urlSuffix将是一个空字符串。这是一个hacky解决方案,但可以工作。

替代使用HTTP_INTERCEPTORS

利用该框架的更清洁的解决方案是HttpInterceptor使用HttpClient并在baseApiUrl文件中设置environment.ts。这允许每个环境使用不同的API端点。

<强> environment.ts

export const environment = {
   apiBaseUrl: 'http://localhost:4200/assets/api',
   production: false
}

<强> development.interceptor.ts

import {Injectable} from '@angular/core';
import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http';
import {Observable} from 'rxjs/Observable';
import {environment} from '../environments/environment';

@Injectable()
export class DevelopmentInterceptor implements HttpInterceptor {
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
  let clonedRequest = null;

    if (!environment.production) {
      clonedRequest = request.clone({
        url: `${request.url}.json`
      });

      return next.handle(clonedRequest);
    }

    return next.handle(clonedRequest);
  }
}

此类将拦截HttpClient发出的任何http请求。使用environment.ts文件中的属性,可以检查当前构建是否为生产构建。如果是,请克隆请求并将.json附加到其中。可以从浏览器访问assets文件夹中的任何内容。以下是映射到网址http:localhost:4200/assets/api/test.json的示例文件。

<强> /src/assets/api/test.json

{
  "name": "test",
  "description": "Test Data"
}

将此文件放在assets目录中,并使目录结构遵循实际API的端点。

<强> test.service.ts

import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {Observable} from 'rxjs/Observable';

import {environment} from '../environments/environment';

@Injectable()
export class TestService {
  private baseUrl = `${environment.apiBaseUrl}/test`;

  constructor(private http: HttpClient) {
  }

  getTestData(): Observable<any> {
    return this.http.get(this.baseUrl);
  }
}

在此处导入environment.ts文件,并将基本网址设置为apiBaseurl属性。只要您导入environment.ts文件而不是environment.prod.ts文件,这将适用于所有环境,因为在构建应用程序时将读取相应的环境文件。所以这个网址只需要在每个环境的一个地方进行更改。

Angular CLI Build Targets & Environment Files

<强> app.component.ts

import {Component, OnInit} from '@angular/core';
import {TestService} from './test.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  title = 'app';

  constructor(private testService: TestService) {
  }

  ngOnInit() {
    this.testService.getTestData().subscribe(
      (testData) => console.log(testData)
    );
  }
}

此处TestService注入AppComponent,调用getTestData()方法从API获取数据。 DevelopmentInterceptor检查environment并将.json附加到请求中。然后将数据记录到控制台。

<强> app.module.ts

import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import {HTTP_INTERCEPTORS, HttpClientModule} from '@angular/common/http';

import {AppComponent} from './app.component';
import {DevelopmentInterceptor} from './development.interceptor';
import {TestService} from './test.service';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule
  ],
  providers: [
    TestService,
    {
      provide: HTTP_INTERCEPTORS,
      useClass: DevelopmentInterceptor,
      multi: true
    }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {
}

注册TestServiceDevelopmentInterceptor作为提供商。

使用此设置,无需proxy.config.json

有关HttpInterceptors的详细信息,请参阅Angular文档Intercepting Http Requests & Responses

Jason Watmore还有一个教程,用这种方法做一些更高级的事情。 Angular 5 - Mock Backend Example for Backendless Development