我正在尝试为所有有角度的2个http请求设置基本网址。以下是我的申请的基本设置。
class HttpOptions extends BaseRequestOptions {
url:string = "http://10.7.18.21:8080/api/";
}
bootstrap(AppComponent, [
HTTP_PROVIDERS,
provide(RequestOptions, {useClass: HttpOptions})
]);
export class AppComponent {
users:Array<User>
constructor(private http: Http) {
http.get("/users")
.subscribe(res => this.users = res.json());
}
}
请求不会像我预期的配置一样发送到http://10.7.18.21:8080/api/users。而是将请求发送到http://localhost:8000/users。
如何在角度2应用程序中为http请求设置基本网址?
我正在使用 Angular 2.0.0-beta.0 。
答案 0 :(得分:45)
适用于角度4.3+和@ angular / common / http
拦截器很简单
@Injectable()
export class ExampleInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const url = 'http://myurl.com';
req = req.clone({
url: url + req.url
});
return next.handle(req);
}
}
app.module.ts
import { NgModule } from '@angular/core';
import { Injectable } from '@angular/core';
import { HttpClientModule, HttpRequest, HTTP_INTERCEPTORS } from '@angular/common/http';
@NgModule({
declarations: [
AppComponent,
...
],
imports: [
BrowserModule,
HttpClientModule,
...
],
providers: [
AppComponent,
{ provide: HTTP_INTERCEPTORS, useClass: ExampleInterceptor, multi: true }
],
bootstrap: [ AppComponent ]
})
export class AppModule { }
编辑:在Angular 4.3中引入了HttpClient和HttpInterceptor
答案 1 :(得分:17)
更新:请参阅Angular 4的@vegazz答案。
对于Angular 2.2.1,以下内容应为web api base url的前缀,并表示占用空间较小:
import {Request, XHRBackend, XHRConnection} from '@angular/http';
@Injectable()
export class ApiXHRBackend extends XHRBackend {
createConnection(request: Request): XHRConnection {
if (request.url.startsWith('/')){
request.url = 'http://localhost:3000' + request.url; // prefix base url
}
return super.createConnection(request);
}
}
在app.module.ts中注入提供者:
providers: [
{ provide: XHRBackend, useClass: ApiXHRBackend }
]
用法示例:
this._http.post('/api/my-route', {foo: 'bar'})
.map<MyResponse>(res => res.json())
它似乎涵盖了所有方法(GET,PUT,POST,...)
答案 2 :(得分:11)
来自RC5的Angular标记HTTP_PROVIDERS
已弃用且尝试将内容移至@NgModule
,上述解决方案并不适用,因此作为其文档。我交叉了几个其他答案并找到了实现基本网址的方法,希望这可能对其他人有所帮助。
基本的想法是,我们不是在引导程序中做事,而是将事情移到AppModule
。
<强> app.module.ts 强>
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpModule, RequestOptions } from '@angular/http';
import { CustomRequestOptions } from './customrequest.options';
@NgModule({
declarations: [
AppComponent,
...
],
imports: [
BrowserModule,
HttpModule,
...
],
providers: [
{ provide: RequestOptions, useClass: CustomRequestOptions }
],
bootstrap: [ AppComponent ]
})
将CustomRequestOptions移动到单独的可注射服务
import { Injectable } from '@angular/core';
import { BaseRequestOptions, RequestOptions, RequestOptionsArgs } from '@angular/http';
@Injectable()
export class CustomRequestOptions extends BaseRequestOptions {
merge(options?:RequestOptionsArgs):RequestOptions {
options.url = 'http://localhost:9080' + options.url;
return super.merge(options);
}
}
如果您尝试发送GET以外的请求类型,则之前的方法无法将baseurl注入请求中。这是因为Angular2会生成除RequestOptions
以外的新this._defaultOptions
,其合并方法不会被我们的CustomRequestOptions覆盖。 (参见此处的source code)。
因此,我没有在CustomRequestOptions合并方法的最后一步中返回super.merge(...)
,而是生成了CustomRequestOptions
的新实例,以确保以下操作仍然有效。
import { Injectable } from '@angular/core';
import { RequestOptions, RequestOptionsArgs } from '@angular/http';
@Injectable()
export class CustomRequestOptions extends RequestOptions {
merge(options?: RequestOptionsArgs): RequestOptions {
if (options !== null && options.url !== null) {
options.url = 'http://localhost:9080' + options.url;
}
let requestOptions = super.merge(options)
return new CustomRequestOptions({
method: requestOptions.method,
url: requestOptions.url,
search: requestOptions.search,
headers: requestOptions.headers,
body: requestOptions.body,
withCredentials: requestOptions.withCredentials,
responseType: requestOptions.responseType
});
}
}
这适用于POST,PUT,DELETE方法。希望这有用。
答案 3 :(得分:6)
在 Angular 2.0.0-beta.6 中你可以通过覆盖'merge'来实现这一目标
import {BaseRequestOptions, RequestOptions, RequestOptionsArgs} from 'angular2/http';
export class ApRequestOptions extends BaseRequestOptions {
merge(options?:RequestOptionsArgs):RequestOptions {
options.url = 'http://10.7.18.21:8080/api' + options.url;
return super.merge(options);
}
}
答案 4 :(得分:5)
查看BaseRequestOptions
,RequestOptions
和Http
类的代码来源后:
url
属性似乎对应于默认网址,但不是网址的前缀。
为了实现你的用例,我建议把一个服务放在http对象的前面然后注入服务。这样的事情:
import {Injectable} from '@angular/core';
import {Http} from '@angular/http';
@Injectable()
export class HttpClient {
http: Http;
urlPrefix: string;
constructor(http: Http) {
this.http = http;
this.urlPrefix = 'http://...';
}
get(url) {
return this.http.get(this.urlPrefix + url);
}
post(url, data) {
return this.http.post(this.urlPrefix + url, data);
}
}
和
import {HttpClient} from './http-client';
export classMyComponent {
constructor(httpClient: HttpClient) {
this.httpClient = httpClient;
}
handleSomething() {
this.httpClient.post(url, data)
).subscribe(...);
}
}
那说也许可以贡献给Angular2本身; - )
希望它可以帮到你, 亨利
答案 5 :(得分:4)
不同的方法:在开发中在localhost中运行您的应用程序时,请考虑配置代理。
proxy.conf.json
{
"/api/**": {
"target": "http://10.7.18.21:8080/",
"secure": false,
"logLevel": "debug"
}
}
更多:link
答案 6 :(得分:1)
import {LocationStrategy} from 'angular2/router';
constructor(private locationStrategy:LocationStrategy) {
console.log(locationStrategy.prepareExternalUrl('xxx'));
}
答案 7 :(得分:0)
对于当前用户,这是 angular 2.4.8
中的实际示例here是分割和链接 BaseCommonRequestOptions 和 CommonRequestOptions 的原因的代码。
import { BaseRequestOptions, Headers, RequestOptions, RequestOptionsArgs } from '@angular/http';
import { Injectable } from '@angular/core';
@Injectable()
export class BaseCommonRequestOptions extends BaseRequestOptions {
merge(options?: RequestOptionsArgs): RequestOptions {
return new CommonRequestOptions(super.merge(extracted(options)));
}
}
/**
* for inner merge when using post put patch delete...others method
*/
export class CommonRequestOptions extends RequestOptions {
merge(options?: RequestOptionsArgs): RequestOptions {
return new RequestOptions(super.merge(extracted(options)));
}
}
/**
* inject default values
*
* @param options
* @returns {RequestOptionsArgs}
*/
export function extracted(options: RequestOptionsArgs) {
console.log(options);
if (!validUrl(options.url)) {
options.url = 'http://localhost:3000' + (options.url ? options.url : "");
}
// use default header application/json, if content-type header was empty.
if (options.headers != null) {
let contentType = options.headers.get('content-type');
if (contentType == null || contentType == '') {
options.headers.append('content-type', 'application/json');
}
} else {
options.headers = new Headers({ 'content-type': 'application/json' });
}
return options;
}
/**
* validate url
*
* @param url
* @returns {boolean}
*/
export function validUrl(url: string) {
return /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/.test(url);
}
答案 8 :(得分:0)
创建.ts文件
import { Injectable } from '@angular/core';
import {Request, XHRBackend, XHRConnection} from '@angular/http';
@Injectable()
export class ApiXHRBackend extends XHRBackend {
createConnection(request: Request): XHRConnection {
if (request.url.startsWith('/api')){
var url=request.url.replace("/api", "");
request.url = 'http://localhost:8080' + url; // prefix base url
}
return super.createConnection(request);
}
}
然后在app.module.ts
import { ApiXHRBackend } from './guard/httpintercepter';
import {Request, XHRBackend, XHRConnection} from '@angular/http';
在供应商部分添加提供商
providers: [
{provide: XHRBackend, useClass: ApiXHRBackend }
],
然后在你的service.ts http调用必须如下面的例子
return this._http.post("/api/customerservice/loginvalidation",data)
.map((response: Response) => {
return response;
});
此处/ api将替换为您的基本网址http://localhost:8080
更多细节 http://shabeen.in/webschool/how-to-set-angular-2-service-http-base-url/