您现在的位置是:首页 > 技术教程 正文

记:vite3+vue3+axios前端项目跨域问题解决【前端和服务器nginx配置】

admin 阅读: 2024-03-27
后台-插件-广告管理-内容页头部广告(手机)

前言:什么是跨域,网上一搜一大把,所以这里直接跳过,直入主题。

处理方式:不通过后端处理跨域,通过前端+服务器nginx处理。

1.前端涉及处理跨域的必要配置(开发环境、生产环境):vite3、vue3、axios

2.服务器涉及处理跨域的配置(生产环境):nginx【主要用到其配置文件nginx.conf】

3.配置开发环境【跟目录下分别创建:.env.development、.env.production】

        .env.development内容如下:

VITE_APP_PROXY_BASE_API='/proxyCustomerApi-dev'

        .env.production内容如下:

VITE_APP_PROXY_BASE_API='/proxyCustomerApi-pro'

     tips: .env.development、.env.production中的常量命名须以"VITE_"开头,这里定义的常量为VITE_APP_PROXY_BASE_API,值分别为"/proxyCustomerApi-dev"、"/proxyCustomerApi-pro"用以区分开发环境和生产环境,值可自定义为"/+自己想定义的内容"

4.前端vite.config.js中添加如下代码(代码中有相关注释):

  1. import { defineConfig, loadEnv } from 'vite';
  2. import vue from '@vitejs/plugin-vue';
  3. import * as path from 'path';
  4. ... ...
  5. export default defineConfig((env) => {
  6. // 获取到当前开发模式(dev/pro)下对应的环境文件对象值
  7. const evnMap = loadEnv(env.mode, process.cwd());
  8. // console.log(`evnMap = ${JSON.stringify(evnMap)}`);
  9. return {
  10. ... ...
  11. server: {
  12. host: '0.0.0.0', // ip地址
  13. port: 8088, // 启动端口
  14. // 反向代理配置,注意rewrite写法,开始没看文档在这里踩了坑
  15. proxy: {
  16. // 本地开发环境通过代理实现跨域,生产环境使用 nginx 转发
  17. // 对应项目根目录 - [.env.development、.env.production]文件中的值
  18. [evnMap.VITE_APP_PROXY_BASE_API]: {
  19. target: 'http://xxx.xx.xx.xx:27005', // 请求报跨域错误的接口域名地址,真实请求地址
  20. changeOrigin: true, // 支持跨域
  21. rewrite: (path) =>
  22. path.replace(new RegExp('^' + evnMap.VITE_APP_PROXY_BASE_API), ''), // 重写真实路径,替换/api
  23. bypass: (req, res, options) => {
  24. const proxyUrl = options.target + options.rewrite(req.url);
  25. console.log(`真实请求的完整地址proxyUrl: ${proxyUrl}`);
  26. },
  27. },
  28. },
  29. },
  30. };
  31. });

5.在自己封装好的axios js文件中修改下axios.create中的配置,代码如下:

  1. const http = axios.create({
  2. // baseURL: DOMAIN,
  3. // import.meta.env.VITE_APP_PROXY_BASE_API 对应项目根目录 - [.env.development、.env.production]文件中的值
  4. baseURL: import.meta.env.VITE_APP_PROXY_BASE_API,
  5. timeout: 600000,
  6. ... ...
  7. });
  8. export default http;

6.在自己出现跨域报错的接口处修改成类似如下代码片段:

  1. export const chatHistoryRecordApi = {
  2. // 获取所有客服与用户对话列表
  3. getAllCustomerChatListPage: (params) => {
  4. return http({
  5. // import.meta.env.VITE_APP_PROXY_BASE_API 对应项目根目录 - [.env.development、.env.production]文件中的值
  6. baseURL: import.meta.env.VITE_APP_PROXY_BASE_API,
  7. url: `/customer/allChatList`,
  8. method: 'get',
  9. params,
  10. });
  11. },
  12. // 查询指定对话的聊天历史记录
  13. queryCurrentChatHistory: (params) => {
  14. return http({
  15. // import.meta.env.VITE_APP_PROXY_BASE_API 对应项目根目录 - [.env.development、.env.production]文件中的值
  16. baseURL: import.meta.env.VITE_APP_PROXY_BASE_API,
  17. url: `/customer/chatHistory`,
  18. method: 'get',
  19. params,
  20. });
  21. },
  22. };

至此前端跨域配置部分处理完成,可以调试开发环境【本地调试】了。

确保根目录下的package.json文件中存在scripts标签配置:

  1. {
  2. "name": "hrosass",
  3. "private": true,
  4. "version": "0.0.0",
  5. "type": "module",
  6. "scripts": {
  7. // dev、build系统会默认添加--mode production/development环境配置
  8. // "dev": "vite" =》"dev": "vite --mode development"
  9. // "build": "vite build" =》"build": "vite build --mode production"
  10. "dev": "vite",
  11. "build": "vite build",
  12. ... ...
  13. },
  14. "dependencies": {
  15. ... ...
  16. },
  17. "devDependencies": {
  18. ... ...
  19. },
  20. "main": "index.js",
  21. ... ...
  22. }

本地调试命令行中执行(我项目是用的yarn来运行):yarn run dev,发现接口可以请求拿到数据了。但在线上生产环境下还是会报错,如果只需要本地调试那到这里就完成了!!!

接下来处理生产环境(线上模式)下的跨域报错问题,由于刚刚前端的配置中已经加上了对生产环境的代理配置,其实也就是根目录下的这个文件【.env.production】。

7.本地连接上服务器,且服务器已配置好Nginx,找到Nginx的运行配置文件【nginx.conf】,内容大致如下(注意看注释):

  1. # For more information on configuration, see:
  2. # * Official English Documentation: http://nginx.org/en/docs/
  3. # * Official Russian Documentation: http://nginx.org/ru/docs/
  4. user nginx;
  5. worker_processes auto;
  6. error_log /var/log/nginx/error.log;
  7. pid /run/nginx.pid;
  8. # Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
  9. include /usr/share/nginx/modules/*.conf;
  10. events {
  11. worker_connections 1024;
  12. }
  13. http {
  14. log_format main '$remote_addr - $remote_user [$time_local] "$request" '
  15. '$status $body_bytes_sent "$http_referer" '
  16. '"$http_user_agent" "$http_x_forwarded_for"';
  17. access_log /var/log/nginx/access.log main;
  18. sendfile on;
  19. tcp_nopush on;
  20. tcp_nodelay on;
  21. keepalive_timeout 65;
  22. types_hash_max_size 4096;
  23. client_max_body_size 20M;
  24. include /etc/nginx/mime.types;
  25. default_type application/octet-stream;
  26. # Load modular configuration files from the /etc/nginx/conf.d directory.
  27. # See http://nginx.org/en/docs/ngx_core_module.html#include
  28. # for more information.
  29. include /etc/nginx/conf.d/*.conf;
  30. map $http_upgrade $connection_upgrade {
  31. default upgrade;
  32. '' close;
  33. }
  34. # 加载vue前端项目的server
  35. server {
  36. listen 3004; # 端口
  37. server_name localhost; # 域名
  38. location / {
  39. root /home/view/wallet/dist/; # 打包vue项目后的dist存放路径
  40. index index.html index.htm; # 加载入口html文件
  41. try_files $uri $uri/ /index.html;
  42. }
  43. error_page 500 502 503 504 /50x.html;
  44. location = /50x.html {
  45. root html;
  46. }
  47. }
  48. # Settings for a TLS enabled server.
  49. #
  50. # server {
  51. # listen 443 ssl http2;
  52. # listen [::]:443 ssl http2;
  53. # server_name _;
  54. # root /usr/share/nginx/html;
  55. #
  56. # ssl_certificate "/etc/pki/nginx/server.crt";
  57. # ssl_certificate_key "/etc/pki/nginx/private/server.key";
  58. # ssl_session_cache shared:SSL:1m;
  59. # ssl_session_timeout 10m;
  60. # ssl_ciphers PROFILE=SYSTEM;
  61. # ssl_prefer_server_ciphers on;
  62. #
  63. # # Load configuration files for the default server block.
  64. # include /etc/nginx/default.d/*.conf;
  65. #
  66. # error_page 404 /404.html;
  67. # location = /40x.html {
  68. # }
  69. #
  70. # error_page 500 502 503 504 /50x.html;
  71. # location = /50x.html {
  72. # }
  73. # }
  74. }

8.往server { location / { } }下边添加如下location反向代理配置(注意看注释):

  1. # /proxyCustomerApi-pro为前端 .env.production中的指定的值
  2. location /proxyCustomerApi-pro {
  3. # 解决跨域
  4. add_header 'Access-Control-Allow-Origin' '*' always;
  5. add_header 'Access-Control-Allow-Credentials' 'true' always;
  6. add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
  7. add_header 'Access-Control-Allow-Headers' 'Authorization,Refreshtoken,DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type' always;
  8. # 设置 options 请求处理
  9. if ($request_method = 'OPTIONS') {
  10. add_header 'Access-Control-Allow-Origin' '*' always;
  11. add_header 'Access-Control-Max-Age' 1728000 always;
  12. add_header 'Content-Type' 'text/plain; charset=utf-8' always;
  13. add_header 'Content-Length' 0 always;
  14. # 对于Options方式的请求返回200或其它码,表示接受跨域请求
  15. return 200;
  16. }
  17. # 设置反向代理 http://://xxx.xx.xx.xx:27005不加/会拼上/proxyCustomerApi-pro 加/不会拼/proxyCustomerApi-pro 由于真实接口请求中没有/proxyCustomerApi-pro这段 这里不需要拼上 代理服务地址后应添加/ http://xxx.xx.xx.xx:27005/
  18. proxy_pass http://://xxx.xx.xx.xx:27005/; # 后端API地址 引起跨域报错的api请求地址
  19. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  20. proxy_set_header Host $http_host;
  21. proxy_set_header X-NginX-Proxy true;
  22. proxy_http_version 1.1;
  23. proxy_connect_timeout 600;
  24. proxy_read_timeout 600;
  25. proxy_send_timeout 600;
  26. proxy_buffer_size 64k;
  27. proxy_buffers 4 64k;
  28. proxy_busy_buffers_size 128k;
  29. proxy_temp_file_write_size 128k;
  30. # 缓存时间,单位秒。这里设置的是6小时
  31. expires 21600s;
  32. # 收到304响应后,再次请求的时间间隔
  33. proxy_cache_valid 200 304 12h;
  34. }

9.配置后的nginx.conf完整内容如下:

  1. # For more information on configuration, see:
  2. # * Official English Documentation: http://nginx.org/en/docs/
  3. # * Official Russian Documentation: http://nginx.org/ru/docs/
  4. user nginx;
  5. worker_processes auto;
  6. error_log /var/log/nginx/error.log;
  7. pid /run/nginx.pid;
  8. # Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
  9. include /usr/share/nginx/modules/*.conf;
  10. events {
  11. worker_connections 1024;
  12. }
  13. http {
  14. log_format main '$remote_addr - $remote_user [$time_local] "$request" '
  15. '$status $body_bytes_sent "$http_referer" '
  16. '"$http_user_agent" "$http_x_forwarded_for"';
  17. access_log /var/log/nginx/access.log main;
  18. sendfile on;
  19. tcp_nopush on;
  20. tcp_nodelay on;
  21. keepalive_timeout 65;
  22. types_hash_max_size 4096;
  23. client_max_body_size 20M;
  24. include /etc/nginx/mime.types;
  25. default_type application/octet-stream;
  26. # Load modular configuration files from the /etc/nginx/conf.d directory.
  27. # See http://nginx.org/en/docs/ngx_core_module.html#include
  28. # for more information.
  29. include /etc/nginx/conf.d/*.conf;
  30. map $http_upgrade $connection_upgrade {
  31. default upgrade;
  32. '' close;
  33. }
  34. # 加载vue前端项目的server
  35. server {
  36. listen 3004; # 端口
  37. server_name localhost; # 域名
  38. location / {
  39. root /home/view/wallet/dist/; # 打包vue项目后的dist存放路径
  40. index index.html index.htm; # 加载入口html文件
  41. try_files $uri $uri/ /index.html;
  42. }
  43. # /proxyCustomerApi-pro为前端 .env.production中的指定的值
  44. location /proxyCustomerApi-pro {
  45. # 解决跨域
  46. add_header 'Access-Control-Allow-Origin' '*' always;
  47. add_header 'Access-Control-Allow-Credentials' 'true' always;
  48. add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
  49. add_header 'Access-Control-Allow-Headers' 'Authorization,Refreshtoken,DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type' always;
  50. # 设置 options 请求处理
  51. if ($request_method = 'OPTIONS') {
  52. add_header 'Access-Control-Allow-Origin' '*' always;
  53. add_header 'Access-Control-Max-Age' 1728000 always;
  54. add_header 'Content-Type' 'text/plain; charset=utf-8' always;
  55. add_header 'Content-Length' 0 always;
  56. # 对于Options方式的请求返回200或其它码,表示接受跨域请求
  57. return 200;
  58. }
  59. # 设置反向代理 http://://xxx.xx.xx.xx:27005不加/会拼上/proxyCustomerApi-pro 加/不会拼/proxyCustomerApi-pro 由于真实接口请求中没有/proxyCustomerApi-pro这段 这里不需要拼上 代理服务地址后应添加/ http://xxx.xx.xx.xx:27005/
  60. proxy_pass http://://xxx.xx.xx.xx:27005/; # 后端API地址 引起跨域报错的api请求地址
  61. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  62. proxy_set_header Host $http_host;
  63. proxy_set_header X-NginX-Proxy true;
  64. proxy_http_version 1.1;
  65. proxy_connect_timeout 600;
  66. proxy_read_timeout 600;
  67. proxy_send_timeout 600;
  68. proxy_buffer_size 64k;
  69. proxy_buffers 4 64k;
  70. proxy_busy_buffers_size 128k;
  71. proxy_temp_file_write_size 128k;
  72. # 缓存时间,单位秒。这里设置的是6小时
  73. expires 21600s;
  74. # 收到304响应后,再次请求的时间间隔
  75. proxy_cache_valid 200 304 12h;
  76. }
  77. error_page 500 502 503 504 /50x.html;
  78. location = /50x.html {
  79. root html;
  80. }
  81. }
  82. # Settings for a TLS enabled server.
  83. #
  84. # server {
  85. # listen 443 ssl http2;
  86. # listen [::]:443 ssl http2;
  87. # server_name _;
  88. # root /usr/share/nginx/html;
  89. #
  90. # ssl_certificate "/etc/pki/nginx/server.crt";
  91. # ssl_certificate_key "/etc/pki/nginx/private/server.key";
  92. # ssl_session_cache shared:SSL:1m;
  93. # ssl_session_timeout 10m;
  94. # ssl_ciphers PROFILE=SYSTEM;
  95. # ssl_prefer_server_ciphers on;
  96. #
  97. # # Load configuration files for the default server block.
  98. # include /etc/nginx/default.d/*.conf;
  99. #
  100. # error_page 404 /404.html;
  101. # location = /40x.html {
  102. # }
  103. #
  104. # error_page 500 502 503 504 /50x.html;
  105. # location = /50x.html {
  106. # }
  107. # }
  108. }

10.执行nginx命令【sudo service nginx reload】使配置生效,至此线上生产环境跨域配置完成。

调试线上跨域问题是否解决,前端项目执行:yarn run build打包线上版本生成dist文件夹并上传到服务器,刷新线上网址发现接口可以请求拿到数据了。

标签:
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

在线投稿:投稿 站长QQ:1888636

后台-插件-广告管理-内容页尾部广告(手机)
关注我们

扫一扫关注我们,了解最新精彩内容

搜索
排行榜