公司域名注册网站哪个好域名解析系统的英文缩写
news/
2025/10/3 0:15:50/
文章来源:
公司域名注册网站哪个好,域名解析系统的英文缩写,中国美食网站模板免费下载,游戏官网制作最近在工作中#xff0c;需要让运行在容器中的单页面应用程序能够访问外部的RESTful API。这个需求看起来并不困难#xff0c;不过实现起来还是有些曲折的。在此#xff0c;我就将这部分内容总结一下。在入正题之前#xff0c;有个一问题#xff0c;就是为什么要将单页面应… 最近在工作中需要让运行在容器中的单页面应用程序能够访问外部的RESTful API。这个需求看起来并不困难不过实现起来还是有些曲折的。在此我就将这部分内容总结一下。在入正题之前有个一问题就是为什么要将单页面应用放在容器中运行这个问题其实跟“为什么要将应用程序容器化”是一个问题。简单来讲容器化的应用程序可以运行在任何具有容器执行环境的宿主平台上比如可以在Linux系统中运行容器也可以在MacOS或者Windows下使用Docker Desktop for Mac或者Docker for Windows来运行容器化的应用程序。无论在什么平台中运行容器化的应用程序都可以使用统一化的配置方式比如环境变量、虚拟磁盘路径的挂载等并向外界提供一致的访问端点。将应用程序容器化最重要的一点是通过它可以非常方便地将应用程序部署在云环境中使应用程序具有很好的横向扩展能力而且跨云的迁移也变得非常便捷。由此可见通过容器的使用我们可以采用不同的技术来实现应用程序的不同部分然后可以得到统一的部署和运维体验这一点对于微服务架构的实践有着非常深远的意义。在工作中我所接触的系统包含了多个团队的贡献有的团队使用nodejs有的团队使用Scala有的团队使用Go这些独立分散的项目都以一个个独立的服务进行开发和交付最终通过容器化的途径实现了整个应用程序的一体化部署。当然与各种软件架构风格类似微服务架构也是有利有弊并不是所有的项目和团队都应该采用这种架构还是应该根据项目和团队的实际情况来决定软件系统的架构方式这部分内容就不在此过多讨论了。回到本文的主题我会通过一个案例来总结在不同场景下容器化单页面应用访问RESTful API的方式。我们的案例是一个提供名称列表的RESTful API外加一个显示名称列表的前端单页面应用。不必理会什么是“名称列表”它只不过是一个字符串列表。在这里我们也不必关心这个字符串列表包含哪些内容只要让单页面应用能够访问到这个RESTful API即可。继续阅读本文你将了解到这个案例是多么的简单。RESTful API首先创建一个能够返回名称列表的RESTful API实现方式有很多种我选择我熟悉的ASP.NET Core Web API项目来创建RESTful API。在命令行执行以下命令以创建一个ASP.NET Core Web API的项目dotnet new webapi --name NameList.Service然后使用Visual Studio Code编辑器打开该项目删除ValuesController然后新增NamesController当然也可以基于ValuesController修改代码如下using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;using Microsoft.AspNetCore.Mvc;namespace NameList.Service.Controllers{ [Route(api/[controller])] [ApiController] public class NamesController : ControllerBase { [HttpGet] public ActionResultIEnumerablestring Get() new string[] { Brian, Frank, Sunny, Chris }; }}目前我们不需要启用HTTPS重定向将其从Startup.cs中删除同时调整launchSettings.json文件直接侦听http://*:5000然后使用dotnet run命令启动RESTful API使用cURL工具进行测试12$ curl -s http://localhost:5000/api/names[Brian,Frank,Sunny,Chris]API调用成功。为了后续的实验能够顺利进行我们在服务端启用CORSpublic class Startup{ private const string CorsPolicy DefaultCorsPolicy; public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); services.AddCors(options { options.AddPolicy(CorsPolicy, builder { builder.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin(); }); }); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseCors(CorsPolicy); }}接下来开发我们的前端单页面应用以调用该API并将名称列表显示在前端页面。单页面应用同样前端页面也可以采用很多种框架和技术进行开发比如使用React、Vue或者Angular或者直接使用jQuery都可以完成我们的目标。我还是选择我最熟悉的Angular 7依照下面的步骤开发这个单页面应用。首先使用Angular CLI创建我们的应用程序在回答几个问题之后使用默认选项即可前端单页面应用也就创建好了首先在app.modules.ts中启用HttpClientModuleimport { BrowserModule } from angular/platform-browser;import { NgModule } from angular/core;import { AppComponent } from ./app.component;import { HttpClientModule } from angular/common/http;NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, HttpClientModule ], providers: [], bootstrap: [AppComponent]})export class AppModule { }然后在environment.ts和environment.prod.ts中加入RESTful API的BaseURI接着新建一个AppService服务app.service.ts在该服务中提供一个getNames的方法用以调用RESTful API以获取名称列表并将获得的列表返回给调用方import { Injectable } from angular/core;import { HttpClient } from angular/common/http;import { Observable, of } from rxjs;import { catchError, tap } from rxjs/operators;import { environment } from src/environments/environment;Injectable({ providedIn: root})export class AppService { constructor(private http: HttpClient) { } getNames(): Observablestring[] { return this.http.getstring[](${environment.serviceUri}/api/names) .pipe( tap(_ console.log(fetched names)), catchError(this.handleErrorstring[]([])) ); } private handleErrorT(result?: T) { return (error: any): ObservableT { console.error(error); return of(result as T); }; }}然后修改app.component.ts以便在页面初始化的时候调用AppService获取名称列表并将获得的列表保存在变量中import { Component, OnInit } from angular/core;import { AppService } from ./app.service;Component({ selector: app-root, templateUrl: ./app.component.html, styleUrls: [./app.component.css]})export class AppComponent implements OnInit { names: string[]; constructor(private appService: AppService) { } ngOnInit(): void { this.getNames(); } getNames(): void { this.appService.getNames() .subscribe(names this.names names); }}最后修改app.component.html通过HTML将获得的名称列表显示在页面上h2Names/h2ul li *ngForlet name of names span{{name}}/span /li/ul现在将RESTful API运行起来然后使用ng serve命令将前端页面也运行起来应该能够看到下面的效果接下来我们将RESTful API和前端页面编译成容器镜像Docker Images。现在我们将上面开发的单页面应用编译成docker镜像然后让它在容器中运行。在Angular项目的根目录下新建一个Dockerfile内容如下FROM nginx AS baseWORKDIR /appEXPOSE 80FROM node:10.16.0-alpine AS buildRUN npm install -g angular/cli8.0.3WORKDIR /srcCOPY . .RUN npm installRUN ng build --prod --output-path /appFROM base AS finalCOPY --frombuild /app /usr/share/nginx/htmlCMD [nginx, -g, daemon off;]大概介绍一下在上面的Dockerfile中将nginx定义为base image因为最终我会将Angular单页面应用运行在nginx上然后基于node镜像安装Angular CLI并将本地前端代码复制到容器中的/src目录下进行编译最终将编译输出的html、js、css以及相关资源复制到nginx容器的/usr/share/nginx/html目录下最后启动nginx来服务单页面应用站点。现在我们启动RESTful API依旧让其侦听5000端口然后通过以下docker命令启动这个前端单页面应用容器1docker run -it -p 8088:80 namelist-client容器启动后打开浏览器访问8088端口我们可以得到同样的结果可以注意到前端页面会发送请求到http://localhost:5000以获得名称列表整个实验看似已经非常成功但是我们忽略了一个重要问题目前RESTful API的地址在前端代码中是写死hard code的即使是在environment.prod.ts文件中指定也是编译时就已经确定的事情那如果RESTful API部署在不同的机器上或者侦听端口不是5000呢这样的话前端单页面应用是无法访问RESTful API服务的。下面我们就来解决这个问题。有一种比较简单粗暴的办法就是在编译的时候通过持续集成环境的设置将RESTful API的地址写入environment.prod.ts文件中但这样编译出来的容器只能在特定环境下运行否则前端页面还是无法访问RESTful API。要让容器能够通用还是应该在容器启动的时候以环境变量的方式将RESTful API的地址注入到容器中。在此我们讨论两种场景RESTful API独立部署的场景以及RESTful API也以容器的方式运行的场景。RESTful API独立部署的场景首先做个实验将前端Angular项目中environment.prod.ts里的serviceUri改为一个相对路径比如1234export const environment { production: true, serviceUri: /name-service};重新将前端应用编译成docker镜像并执行不出意料页面无法正确加载因为调用的RESTful API地址不正确调用返回404接下来可以使用nginx的反向代理功能将/name-service的部分proxy_pass到真实的RESTful API地址而真实的RESTful API地址可以在nginx的配置中通过读取环境变量来动态设置。在前端代码的根目录下新建nginx.conf文件load_module modules/ngx_http_perl_module.so;env API_URI;events { worker_connections 1024;}http { perl_set $api_uri sub { return $ENV{API_URI}; }; server { listen 80; server_name localhost; include /etc/nginx/mime.types; location / { root /usr/share/nginx/html; index index.html index.htm; } location ~ ^/name-service/(.*)$ { rewrite ^ $request_uri; rewrite ^/name-service/(.*)$ $1 break; return 400; } }}该配置文件通过使用nginx的perl模块读取系统环境变量并在nginx中使用这个环境变量然后设置location指定当客户端请求/name-service时将请求proxy_pass到由API_URI环境变量设置的RESTful API地址。由于需要使用perl模块所以Dockerfile也要做相应修改FROM nginx:perl AS baseWORKDIR /appEXPOSE 80FROM node:10.16.0-alpine AS buildRUN npm install -g angular/cli8.0.3WORKDIR /srcCOPY . .RUN npm installRUN ng build --prod --output-path /appFROM base AS finalCOPY --frombuild /app /usr/share/nginx/htmlCOPY --frombuild /src/nginx.conf /etc/nginx/nginx.confCMD [nginx, -g, daemon off;]Base Image由nginx改为nginxperl然后需要将nginx.conf文件复制到nginx容器中的/etc/nginx目录。之后重新编译前端docker镜像。现在启动容器时就可以使用-e参数指定RESTful API的地址了1docker run -it -p 8088:80 -e API_URI192.168.0.107:5000 namelist-client再次刷新前端页面可以看到页面正确显示API调用成功RESTful API容器化的场景如果我们将RESTful API也容器化并与前端应用一起在容器中运行那么就可以使用容器连接的方式让前端页面访问后端的API。此时只需要对前端nginx.conf进行一些修改events { worker_connections 1024;}http { server { listen 80; server_name localhost; include /etc/nginx/mime.types; location / { root /usr/share/nginx/html; index index.html index.htm; } location ~ ^/name-service/(.*)$ { } } upstream namelist-service { server namelist-service:5000; }}分别使用以下两条命令启动RESTful API和前端应用容器12docker run -it --name namelist-service namelist-servicedocker run -it -p 8088:80 --link namelist-service namelist-client注意到在启动前端应用容器时需要使用—link参数链接到namelist-service容器而且服务端也不需要暴露出TCP端口起到了一定的保护作用本文以容器为背景结合nginx的使用介绍了容器化单页面应用中访问RESTful API的两种方法。由于单页面应用无法读取系统的环境变量因此解决RESTful API访问地址的问题就变得稍微有点复杂。本文相关的案例源代码https://github.com/daxnet/name-list。原文地址https://sunnycoding.cn/2019/06/22/accessing-restful-api-in-dockerized-spa/.NET社区新闻深度好文欢迎访问公众号文章汇总 http://www.csharpkit.com
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/925437.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!