前端如何解决跨域问题(vue-cli、nginx)

文章目录

  • 情景
  • 一、vue脚手架配置代理
    • 写法1(简洁版)
    • 写法2(完整版)
  • 二、nginx配置反向代理
  • 总结

解决跨域的方法有很多,常见的有cors、jsonp、nginx…
本文主要介绍两种方法: vue脚手架配置代理Nginx配置反向代理

情景

我启动了一个关于博客系统的前端项目,
现在要请求博客列表这个接口 http://localhost:8000/blog/list
前端如何解决跨域问题(vue-cli、nginx)_第1张图片
如果不做任何处理,直接在前端项目中请求这个接口,会提示跨域

	// 前端项目发起请求
	axios.get('http://localhost:8000/blog/list').then(
	  response => {
	    console.log('请求成功了', response)
	  },
	  error => {
	    console.log('请求失败了', error.message)
	  }
	)

前端如何解决跨域问题(vue-cli、nginx)_第2张图片
前端如何解决跨域问题(vue-cli、nginx)_第3张图片

一、vue脚手架配置代理

如果你的前端项目正好使用的是vue框架,推荐使用这个方法,便捷且易懂
前提:安装vue-cli
步骤:前端项目的根目录下新建vue.config.js文件,配置代理

写法1(简洁版)

vue.config.js配置详情

module.exports = {
  devServer: {
    proxy: 'http://localhost:8000'
  }
}

请求url写法 /blog/list (不用带host)

axios.get('/blog/list').then(
  response => {
    console.log('请求成功了', response)
  },
  error => {
    console.log('请求失败了', error.message)
  }
)

实际request URL: http://localhost:9001/blog/list
前端如何解决跨域问题(vue-cli、nginx)_第4张图片
说明

  1. 优点:配置简单
  2. 缺点:不能配置多个代理

写法2(完整版)

vue.config.js配置详情

module.exports = {
  devServer: {
    proxy: {
      '/api1': { // 匹配所有以 '/api1'开头的请求路径
        target: 'http://localhost:8000', // 代理目标的基础路径
        changeOrigin: true, //用于控制请求头中的host值
        pathRewrite: { '^/api1': '' }
      },
      '/api2': {
        target: 'http://localhost:5000',
        changeOrigin: true,
        pathRewrite: {'^/api2': ''}
      }      
    }
  }
}

请求url写法 /api1/blog/list (不用带host,但要在路径前带/api1用于命中目标代理)

axios.get('/api1/blog/list').then(
  response => {
    console.log('请求成功了', response)
  },
  error => {
    console.log('请求失败了', error.message)
  }
)

实际request URL: http://localhost:9001/api1/blog/list
前端如何解决跨域问题(vue-cli、nginx)_第5张图片
说明

  1. 优点:可以配置多个代理
  2. 缺点:配置略微繁琐,请求资源时必须加前缀

二、nginx配置反向代理

1、下载nginx

  • Windows : http://nginx.org/en/download.html
  • Mac : brew install nginx

2、打开配置文件 nginx.conf

不同系统的配置文件目录

  • Windows : C:\nginx\conf\nginx.conf
  • Mac : /usr/local/etc/nginx/nginx.conf

nginx.conf具体配置

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;
    server {
        listen       80; # 默认80端口
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

         location /api1/ {
            proxy_pass http://localhost:8000/;  # 如果没有/,会把匹配的路径部分也给代理走
            proxy_set_header Host $host; # 把原http请求的Header中的Host字段也放到转发的请求
			add_header 'Access-Control-Allow-Origin' '*'; # 解决跨域
         }  
         
         location /api2/ {
            proxy_pass http://localhost:5000/; 
            proxy_set_header Host $host;
			add_header 'Access-Control-Allow-Origin' '*'; 
         }  		

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}

请求url写法 http://localhost/api1/blog/list (要带域名,可以不用带端口号,因为浏览器默认请求使用的是80端口)

  axios.get('http://localhost/api1/blog/list').then(
    response => {
      console.log('请求成功了', response)
    },
    error => {
      console.log('请求失败了', error.message)
    }
  )

实际request URL: http://localhost/api1/blog/list
前端如何解决跨域问题(vue-cli、nginx)_第6张图片
说明
nginx也可以配置多个代理,除此之外,还能用于做静态服务、负载均衡等

注意点
1、proxy_pass 最后面要不要加 /

  • 在nginx中配置proxy_pass代理转发时,如果在proxy_pass后面的url最后加/,表示绝对路径;
  • 如果没有/,表示相对路径,把匹配的路径部分也给代理走

例:访问路径为 /blog/list

当nginx配置文件proxy_pass后边的url带" / "时,代理到后端的路径为:http://localhost/blog/list , 省略了匹配到的 /api1/路径;

  location /api1/ {
     proxy_pass http://localhost:8000/;
  }  

当nginx配置文件proxy_pass后边的url不带" / "时,代理到后端的路径为:http://localhost/api1/blog/list,连同匹配到的/api1/路径,一起进行反向代理;

  location /api1/ {
     proxy_pass http://localhost:8000;
  }  

2、如果修改了nginx的默认端口号,前端请求时不可以省略这个端口号
如:把nginx端口号改为8080,请求时url的写法 http://localhost:8080/api1/blog/list

    server {
        listen       8080; // 配置nginx端口
        server_name  localhost;
		....
		}

总结

为什么配置代理服务器可以解决跨域问题?
答:服务器和服务器之间通讯,不用ajax,不存在跨域问题

你可能感兴趣的:(工具使用,前端学习,前端,vue.js,nginx,vue-cli,代理)