在 Angular 中执行 Http get 方法而不重试并等到服务器发送响应?
Posted
技术标签:
【中文标题】在 Angular 中执行 Http get 方法而不重试并等到服务器发送响应?【英文标题】:Perform Http get method in Angular with no retries and wait until server sends the response? 【发布时间】:2018-06-09 08:04:53 【问题描述】:我的控制器中有以下内容,在 Spring-Boot 应用程序中:
@RequestMapping(method=RequestMethod.GET,value="/info")
public DataModel getinfodata()
//this method runs some script which takes more than 3 minutes and sends the response back
return run_xyz()
在我的 Angular 应用程序中,我有这个:
export class FetchService
private _url:string="/info";
constructor(private _http:Http)
getData():any
return this._http.get(this._url).map((res:Response)=>res.json()).
catch(this.errorHandler).subscribe(data=>console.log(data));
errorHandler(error: Response)
console.error(error);
return Observable.throw(error || "Server Error");
我目前面临的问题是 Http get
正在对服务器进行静默重试,结果,我昂贵的脚本被调用了 3 或 4 次。有没有一种方法可以让get
只发出一次请求,重试次数为 0 次,然后等到脚本完成后再发回响应。我只调用一次 getData 方法。
Snapshot of response from backendSnapshot of Tomcat running on port 8080Snapshot of server response in normal case, when the script is not running Angular CLIFinal Response after 189 seconds
【问题讨论】:
***.com/questions/36271899/… 可能会给出一些想法 谢谢,但这也没有帮助。@Günter Zöchbauer 【参考方案1】:http observable 为每个订阅者发出一个 http 请求。所以 3 到 4 个 http 请求意味着你必须有多个组件同时订阅。要为多个观察者共享一个 http 请求,您需要类似 share 运算符。
export class FetchService
data$: Observable<any>;
constructor()
this.data$ = this._http.request(this._url)
.map((res:Response)=>res.json())
.catch(this.errorHandler)
.share();
getData()
return this.data$;
现在多个观察者将共享同一个 observable。
这个操作符是发布的一个特化,它在观察者的数量从零到一时创建一个订阅,然后与所有后续的观察者共享该订阅,直到观察者的数量回到零,此时订阅被释放。
至于您的ERR_EMPTY_RESPONSE
问题。当我的代理 api 调用超时时,我遇到了这个问题。
【讨论】:
我只订阅一次而不是多次,如果在 120 秒(如观察到的)内没有从服务器发送响应,它正在发出另一个请求,则问题在于获取请求。 @VikasSingh 你正在使用 webpack 开发服务器代理? 不,我使用的是 node.js 和 tomcat,老实说我没听说过 webpack 开发服务器代理这个词 @VikasSingh 来自您的图片,我假设您正在使用ng serve
运行 angular cli,因为图片显示 localhost:4200
@VikasSingh 真的 ng serve
应该只用于开发。当使用ng serve
时,如果您的 api 请求与您的应用程序位于同一域中,您将不得不代理它们。因此,您的应用程序正在向 localhost:4200(由 ng serve 托管的应用程序)发出 api 请求,但 api 托管在 localhost:3000 上(假设您使用的是默认节点 js 端口)。所以你需要将 localhost:4200 的 api 请求代理到 localhost:3000。这是 angular cli 中关于使用代理配置的docs【参考方案2】:
最终,我弄清楚了为什么会发生这种情况 开发服务器使用http-proxy-middleware package
More Here 并且此包中提供的代理选项来自底层http-proxy library
http-proxy options。
其中之一是
代理超时:
代理未收到响应时的超时(以毫秒为单位)
如果服务器未能在规定的时间(120 秒)内响应,则默认值为 ~120 秒(根据我的观察),则向服务器发出新请求。
在代理配置文件中使用 "timeout":30000
覆盖默认超时解决了该问题。
"/info":
"target":
"host": "localhost",
"protocol": "http:",
"port": 8080
,
"secure": false,
"changeOrigin": true,
"logLevel": "debug",
"timeout":30000
【讨论】:
以上是关于在 Angular 中执行 Http get 方法而不重试并等到服务器发送响应?的主要内容,如果未能解决你的问题,请参考以下文章