{"id":22903553,"url":"https://github.com/sawyerbutton/angular-cli-proxy-configuration","last_synced_at":"2026-01-08T19:04:40.933Z","repository":{"id":120747975,"uuid":"152954747","full_name":"sawyerbutton/Angular-CLI-Proxy-Configuration","owner":"sawyerbutton","description":"Angular CLI proxy configuration tutorial in CN","archived":false,"fork":false,"pushed_at":"2018-10-14T13:53:01.000Z","size":100,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-07T04:41:16.677Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sawyerbutton.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-10-14T08:39:10.000Z","updated_at":"2018-10-14T13:53:02.000Z","dependencies_parsed_at":"2023-07-07T23:05:52.591Z","dependency_job_id":null,"html_url":"https://github.com/sawyerbutton/Angular-CLI-Proxy-Configuration","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sawyerbutton%2FAngular-CLI-Proxy-Configuration","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sawyerbutton%2FAngular-CLI-Proxy-Configuration/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sawyerbutton%2FAngular-CLI-Proxy-Configuration/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sawyerbutton%2FAngular-CLI-Proxy-Configuration/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sawyerbutton","download_url":"https://codeload.github.com/sawyerbutton/Angular-CLI-Proxy-Configuration/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246599159,"owners_count":20803152,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-14T02:37:47.124Z","updated_at":"2026-01-08T19:04:35.914Z","avatar_url":"https://github.com/sawyerbutton.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Angular-CLI-Proxy-Configuration\n\n## Angular CLI 反向代理配置\n\n\u003e 在使用Angular进行本地开发时，与一个或多个后端服务进行链接是非常常见的状况\n\n\u003e 而使用nginx或Kubernetes Ingress这样的反向代理将请求路由到同一域`(domain)`上不同路径后端服务则是应对此种开发场景的常见方案\n\n\u003e 但是因为有了CLI的存在，可以通过简单的配置解决上述问题\n\n## 从例子说起\n\n\u003e 假设存在一个前端坐落于路径`http://mydomain.com/catlog`上\n\n\u003e `Catalog Server`负责提供静态文件`.js，.css，.html`，并提供一个返回环境配置内容的接口给前端\n\n![frontEnd and back server](./assets/1.png)\n\n\u003e 还有两个rest 接口, `Video API’`和`Library API`分别坐落于\b同一`domain`的`/video/`和`/library/`路径上, 这两个接口提供目录页面期望展示的书籍和电影信息\n\n\u003e 再默认的情况下，\bAngular CLI \b假设前端将会服务在基本路径`/`上，比如 CLI\b 默认在index.html插入`\u003cbase href=\"/\"\u003e`作为基础路径\n\n\u003e 比如当浏览器加载`https://mydomain.com/catalog/index.html`时, 浏览器将从`https://mydomain.com/main.bundle.js`请求`main.bundle.js`文件，但是\b这将会导致一个404错误，因为\b`main.bundle.js`的文件存在于路径`/catalog`上\n\n\u003e 这个问题可以通过指定`base`锚点(`/catlog`)并将其部署与package.json中即可\n\n```json\n{\n    \"start\": \"ng serve --base-href /catalog/ --deploy-url /catalog/\",\n    \"build\": \"ng build --prod --base-href /catalog/ --deploy-url /catalog/\"\n}\n```\n\n_通过在`enviornment.ts`和`environment.prod.ts`中配置额外的属性可以解决\b某些业务\bAPI引用的问题`但并不能解决根本的状况`所以并`不推荐`_\n\n\u003e 如果运行`npm run start`可以生成一个带有`\u003cbase href =\"/ catalog /\"\u003e`的index.html文件，并可以通过访问`http://localhost:4200/catalog/`访问该页面\n\n\u003e 类似的状况包括对于css文件的引用，如果在使用CSS引用字体或图像等资源时遇到问题可以通过类似的方式尝试设置\n\n\u003e 至此项目已经更加符合期望的服务和前端在生产中的部署结构,但是本地已经开始处理静态文件的Angular CLI还是不清楚如何处理类似于下述请求\n- `GET /video/films`\n- `GET /library/books`\n- `GET /catalog/config`\n\n\u003e 为了处理这些额外的请求必须配置Angular CLI以将其代理至能够理解并提供响应的服务器\n\n\u003e 需要在Angular-CLI项目的根目录中创建一个文件`proxy.conf.json`，内容如下\n\n```json\n{\n  \"/library/*\": {\n    \"target\": \"http://localhost:10000\",\n    \"secure\": false,\n    \"logLevel\": \"debug\",\n    \"changeOrigin\": true,\n    \"pathRewrite\": {\n      \"^/library\": \"\"\n    }\n  },\n  \"/video/*\": {\n    \"target\": \"http://localhost:10001\",\n    \"secure\": false,\n    \"logLevel\": \"debug\",\n    \"changeOrigin\": true,\n    \"pathRewrite\": {\n      \"^/video\": \"\"\n    }\n  },\n  \"/catalog/api/*\": {\n    \"target\": \"http://localhost:5000\",\n    \"secure\": false,\n    \"logLevel\": \"debug\",\n    \"changeOrigin\": true,\n    \"pathRewrite\": {\n      \"^/catalog\": \"\"\n    }\n  }\n}\n```\n\n1. `changeOrigin`属性用于后端服务与前端存在跨域时，设置为true\n2. `logLevel`属性用于调试代理是否正常工作(属性包括:`debug,info,warn,error,silent`,默认为`info`)\n\u003e 除此之外，还需要更新`package.json`以在本地运行时引用此文件\n\n```json\n{\n    \"start\": \"ng serve --base-href /catalog/ --deploy-url /catalog/ --proxy-config proxy.conf.json\",\n}\n```\n\n\u003e _或者可以通过将`proxyConfig`导入`angular.json`文件中的方式_\n\n```json\n\"architect\": {\n  \"serve\": {\n    \"builder\": \"@angular-devkit/build-angular:dev-server\",\n    \"options\": {\n      \"browserTarget\": \"your-application-name:build\",\n      \"proxyConfig\": \"proxy.conf.json\"\n    }\n```\n\n\u003e 现在运行`npm run start`指令(或`ng serve`)，命令行将会展示之前的代理设置\n\n![proxy screenshot](./assets/2.jpeg)\n\n\u003e 现在在浏览器内前进到`http://localhost:4200/catalog/`, 从命令行中可以观察到数个被代理到其他服务的请求\n\n![proxy request screenshow](./assets/3.jpeg)\n\n- 发往`http://localhost:4200/library/books`的请求被代理到`http://localhost:10000/books`\n\u003e 因为配置要求任何匹配`/library/*`的路径定向到`http://localhost:10000`服务器;除此之外，`pathRewrite`属性需要改所有满足`^/library`的路径:替换`^/library`为`''`\n\n```\nhttp://localhost:4200/library/books -\u003e http://localhost:4200/books\n```\n\n- 相似的代理状况发生在`http://localhost:4200/catalog/api/config`, `pathRewrite`属性为:`^/catalog/api/*: \"\"`,故而\n\n```\nhttp://localhost:4200/catalog/api/config -\u003e http://localhost:5000/api/config\n```\n\n## 一些例外的情况\n\n### 代理多个条目到同一目标server\n\n\u003e 需要在`proxy.conf.js`中定义配置而不是`proxy.conf.json`中\n\n```javascript\nconst PROXY_CONFIG = [\n    {\n        context: [\n            \"/my\",\n            \"/many\",\n            \"/endpoints\",\n            \"/i\",\n            \"/need\",\n            \"/to\",\n            \"/proxy\"\n        ],\n        target: \"http://localhost:3000\",\n        secure: false\n    }\n]\n\nmodule.exports = PROXY_CONFIG;\n```\n\n\u003e 同样的，需要在`angular.json`文件中正确引入js文件\n\n```json\n\"architect\": {\n  \"serve\": {\n    \"builder\": \"@angular-devkit/build-angular:dev-server\",\n    \"options\": {\n      \"browserTarget\": \"your-application-name:build\",\n      \"proxyConfig\": \"proxy.conf.js\"\n    }\n```\n\n### 需要绕过代理，或在请求发送之前动态更改请求\n\n```javascript\nconst PROXY_CONFIG = {\n    \"/api/proxy\": {\n        \"target\": \"http://localhost:3000\",\n        \"secure\": false,\n        \"bypass\": function (req, res, proxyOptions) {\n            if (req.headers.accept.indexOf(\"html\") !== -1) {\n                console.log(\"Skipping proxy for browser request.\");\n                return \"/index.html\";\n            }\n            req.headers[\"X-Custom-Header\"] = \"yes\";\n        }\n    }\n}\n\nmodule.exports = PROXY_CONFIG;\n```\n\n### 使用企业代理\n\n_存疑_\n\n\u003e 常规配置下，在企业代理中尝试将请求代理到本地网络之外的任何URL将会失败\n\n\u003e 在这种情况下，可以配置后端代理使用一个代理人通过公司的代理重定向请求，需要安装`https-proxy-agent`包并配置\n\n```bash\nnpm i --save-dev https-proxy-agent\n```\n\n```javascript\nvar HttpsProxyAgent = require('https-proxy-agent');\nvar proxyConfig = [{\n  context: '/api',\n  target: 'http://your-remote-server.com:3000',\n  secure: false\n}];\n\nfunction setupForCorporateProxy(proxyConfig) {\n  var proxyServer = process.env.http_proxy || process.env.HTTP_PROXY;\n  if (proxyServer) {\n    var agent = new HttpsProxyAgent(proxyServer);\n    console.log('Using corporate proxy server: ' + proxyServer);\n    proxyConfig.forEach(function(entry) {\n      entry.agent = agent;\n    });\n  }\n  return proxyConfig;\n}\n\nmodule.exports = setupForCorporateProxy(proxyConfig);\n```\n\n\u003e 当定义了http_proxy或HTTP_PROXY环境变量之后，运行时代理人将会自动添加到请求上并通过企业代理\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsawyerbutton%2Fangular-cli-proxy-configuration","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsawyerbutton%2Fangular-cli-proxy-configuration","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsawyerbutton%2Fangular-cli-proxy-configuration/lists"}