vue2_vite.config.js的proxy跨域配置和nginx配置代理有啥区别?

简介: vue2_vite.config.js的proxy跨域配置和nginx配置代理有啥区别?

背景

vue的项目在开发到生产上线的初期最容易遇到的问题就是跨域。浏览器安全机制导致的,配置api代理只是本地的,所以经常需要再服务器的nginx做一个后端接口的nginx反向代理

vite.config.js配置代理

简单粗暴的看下vue2的配置

个人项目网站的配置如下

webpack的配置

proxyTable: {
      "/api/": {
        target: "https://yongma16.xyz/", //后端接口地址
        ws: true, //接受websocket请求
        changeOrigin: true, //是否允许跨越
        chunkOrigins: true,
        pathRewrite: {
          "^/api": "api", //重写,
        },
      },
      "/ws_api/": {
        target: "wss://yongma16.xyz/ws/webchat/",
        ws: true, //接受websocket请求
        changeOrigin: true, //是否允许跨越
        chunkOrigins: true,
        pathRewrite: {
          "^/ws_api": "", //重写,
        },
      },
    }

vue.config.js的配置

proxy: {
      "^/cloudApi/": {
        target: "https://yongma16.xyz/back-front",
        // target: "http://localhost:9090/",
        changeOrigin: true,
        ws: true,
        rewrite: (path) => path.replace(/^\/cloudApi/, ""),
      },
    },

跨域鼻祖 jsonp

经常写html 我们知道拿个src可以跨域

没错,JSONP实现跨域就是通过html的标签的src去获取跨域请求内容

简陋版

// 前端部分
<script>
    // 1 callback
    // 2 后端 callbackName(数据)
    function onResponse(posts) {
        console.log(posts);
    }
    // 前端没有调用
</script>
<!-- 后端返回结果 -->
<!-- 调用 -->
<script src="http://localhost:9090/api"></script>
//后端部分
const http = require('http');
http.createServer((req, res) => {
    if (req.url === '/api') {
        let posts = ['js', 'php'];
        res.end(`onResponse(${JSON.stringify(posts)})`);
    }
})
.listen(9090, () => {
    console.log(9090)
})

前端json p的跨域

// 前端(代码放在body中执行)
<script>
  function jsonp(url, options) {
    // 超时处理
    const { timeout } = options;
    return new Promise((resolve, reject) => {
      // 防止函数名冲突
      let funcName = `jsonp${Date.now()}`;
      let time =  null, scriptNode;
      // 定义callback
      window[funcName] = function(data) {
        if (timeout) clearTimeout(time);
        resolve(data);
        // 很重要的性能优化点
        // 清除本次请求产生的回调函数和script标签
        delete window[funcName];
        document.body.removeChild(scriptNode);
      }
      // 创建script标签
      scriptNode = document.createElement('script');
      // 给script标签添加src属性
      scriptNode.src = `${url}?callback=${funcName}`;
      // 发出请求
      document.body.appendChild(scriptNode);
      time = setTimeout(() => {
        reject('network err, timeout')
      }, timeout)
      // 失败
      scriptNode.onerror = function(err) {
      reject(err);
      }
    })
  }
  jsonp('http://localhost:9090/api', {
    callBack: 'res1',
    // 超时处理
    timeout: 3000
  })
  // 请求成功
  .then(res => {
    console.log('jsonp->', res);
  })
  // 请求失败
  .catch(err => {
      console.log("network err!")
  })
</script>

如下是ajax封装之后的调用

$.ajax({
    url: "http://127.0.0.1/~chenjiebin/mycode/php/crossdomain/index.php",
    dataType: "jsonp",
    jsonp: "callback",
    context: document.body,
    success: function(data) {
        console.log(data);
    }
});

ok,那么axios也可以使用jsonp产生跨域

譬如

axios.jsonp = (url,data)=>{
    if(!url)
        throw new Error('url is necessary')
    const callback = 'CALLBACK' + Math.random().toString().substr(9,18)
    const JSONP = document.createElement('script')
          JSONP.setAttribute('type','text/javascript')
    const headEle = document.getElementsByTagName('head')[0]
    let ret = '';
    if(data){
        if(typeof data === 'string')
            ret = '&' + data;
        else if(typeof data === 'object') {
            for(let key in data)
                ret += '&' + key + '=' + encodeURIComponent(data[key]);
        }
        ret += '&_time=' + Date.now();
    }
    JSONP.src = `${url}?callback=${callback}${ret}`;
    return new Promise( (resolve,reject) => {
        window[callback] = r => {
          resolve(r)
          headEle.removeChild(JSONP)
          delete window[callback]
        }
        headEle.appendChild(JSONP)
    })
    
}

ok,相信到这,我们可能会猜想vue.config的proxy代理是否页用了jsonp,去看看!

vue proxy用了jsonp吗(并不是)

ctrl点击去查看源代码,走你

哦吼,看见只是他的类型定义。

不急,咋们已经看见这是axios的拦截配置项了。

去axios一探究竟

axios是基于promise的网络请求库,由node发起请求。

http的Proxy包括协议 域名 端口

我们找到的是http的服务代理,node开一个web服务器去代理请求,所以不是jsonp

vue项目中的node开启了web服务器代理转发了请求
export class Server extends events.EventEmitter {
        /**
         * Creates the proxy server with specified options.
         * @param options - Config object passed to the proxy
         */
        constructor(options?: ServerOptions)
        /**
         * Used for proxying regular HTTP(S) requests
         * @param req - Client request.
         * @param res - Client response.
         * @param options - Additional options.
         */
        web(
        req: http.IncomingMessage,
        res: http.ServerResponse,
        options?: ServerOptions,
        callback?: ErrorCallback,
        ): void
        /**
         * Used for proxying regular HTTP(S) requests
         * @param req - Client request.
         * @param socket - Client socket.
         * @param head - Client head.
         * @param options - Additional options.
         */
        ws(
        req: http.IncomingMessage,
        socket: unknown,
        head: unknown,
        options?: ServerOptions,
        callback?: ErrorCallback,
        ): void
        /**
         * A function that wraps the object in a webserver, for your convenience
         * @param port - Port to listen on
         */
        listen(port: number): Server
        /**
         * A function that closes the inner webserver and stops listening on given port
         */
        close(callback?: () => void): void
        /**
         * Creates the proxy server with specified options.
         * @param options - Config object passed to the proxy
         * @returns Proxy object with handlers for `ws` and `web` requests
         */
        static createProxyServer(options?: ServerOptions): Server
        /**
         * Creates the proxy server with specified options.
         * @param options - Config object passed to the proxy
         * @returns Proxy object with handlers for `ws` and `web` requests
         */
        static createServer(options?: ServerOptions): Server
        /**
         * Creates the proxy server with specified options.
         * @param options - Config object passed to the proxy
         * @returns Proxy object with handlers for `ws` and `web` requests
         */
        static createProxy(options?: ServerOptions): Server
        addListener(event: string, listener: () => void): this
        on(event: string, listener: () => void): this
        on(event: 'error', listener: ErrorCallback): this
        on(
        event: 'start',
        listener: (
        req: http.IncomingMessage,
        res: http.ServerResponse,
        target: ProxyTargetUrl,
        ) => void,
        ): this
        on(
        event: 'proxyReq',
        listener: (
        proxyReq: http.ClientRequest,
        req: http.IncomingMessage,
        res: http.ServerResponse,
        options: ServerOptions,
        ) => void,
        ): this
        on(
        event: 'proxyRes',
        listener: (
        proxyRes: http.IncomingMessage,
        req: http.IncomingMessage,
        res: http.ServerResponse,
        ) => void,
        ): this
        on(
        event: 'proxyReqWs',
        listener: (
        proxyReq: http.ClientRequest,
        req: http.IncomingMessage,
        socket: net.Socket,
        options: ServerOptions,
        head: any,
        ) => void,
        ): this
        on(
        event: 'econnreset',
        listener: (
        err: Error,
        req: http.IncomingMessage,
        res: http.ServerResponse,
        target: ProxyTargetUrl,
        ) => void,
        ): this
        on(
        event: 'end',
        listener: (
        req: http.IncomingMessage,
        res: http.ServerResponse,
        proxyRes: http.IncomingMessage,
        ) => void,
        ): this
        on(
        event: 'close',
        listener: (
        proxyRes: http.IncomingMessage,
        proxySocket: net.Socket,
        proxyHead: any,
        ) => void,
        ): this
        once(event: string, listener: () => void): this
        removeListener(event: string, listener: () => void): this
        removeAllListeners(event?: string): this
        getMaxListeners(): number
        setMaxListeners(n: number): this
        listeners(event: string): Array<() => void>
        emit(event: string, ...args: any[]): boolean
        listenerCount(type: string): number
    }

nginx代理

proxy代理请求,proxy_pass。

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       80;
        server_name  localhost;
        location / {
            root   html;
            index  index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html;
        location /api {
            proxy_pass https://yongma16.xyz/api;
        }
  }
}
结尾

vue和nginx都对请求做了一次转发

vue是基于客户端如windows

nginx是基于生产服务器的如centos

在打包前端项目到服务器的时候

由于前端是静态文件

产生协议域名端口的跨域时

需要用到nginx反向代理后端端口地址

结束

感谢阅读,如有不足欢迎指出!


目录
相关文章
|
2月前
|
监控 应用服务中间件 测试技术
确保正则表达式在 Nginx 代理中的准确性和稳定性
【10月更文挑战第19天】总之,正则表达式在 Nginx 代理中具有重要作用,但要确保其准确性和稳定性需要付出一定的努力和关注。通过以上方法的综合运用,我们可以提高正则表达式配置的可靠性,为用户提供更好的服务体验。
|
1月前
|
前端开发 应用服务中间件 定位技术
Nginx 如何代理转发传递真实 ip 地址?
【10月更文挑战第32天】
229 5
Nginx 如何代理转发传递真实 ip 地址?
|
1月前
|
JavaScript 前端开发
js中的bind,call,apply方法的区别以及用法
JavaScript中,`bind`、`call`和`apply`均可改变函数的`this`指向并传递参数。其中,`bind`返回一个新函数,不立即执行;`call`和`apply`则立即执行,且`apply`的参数以数组形式传递。三者在改变`this`指向及传参上功能相似,但在执行时机和参数传递方式上有所区别。
26 1
|
1月前
|
应用服务中间件 网络安全 nginx
轻松上手Nginx Proxy Manager:安装、配置与实战
Nginx Proxy Manager (NPM) 是一款基于 Nginx 的反向代理管理工具,提供直观的 Web 界面,方便用户配置和管理反向代理、SSL 证书等。本文档介绍了 NPM 的安装步骤,包括 Docker 和 Docker Compose 的安装、Docker Compose 文件的创建与配置、启动服务、访问 Web 管理界面、基本使用方法以及如何申请和配置 SSL 证书,帮助用户快速上手 NPM。
209 1
|
1月前
|
负载均衡 前端开发 JavaScript
Nginx 代理多服务
以上是 Nginx 代理多服务的几种常见方式,在实际应用中,可以根据具体的业务需求和系统架构选择合适的代理方式,并结合其他 Nginx 的功能和配置来优化和完善系统的性能和功能。
|
1月前
|
设计模式 JavaScript 前端开发
js中new和object.creat区别
【10月更文挑战第29天】`new` 关键字和 `Object.create()` 方法在创建对象的方式、原型链继承、属性初始化以及适用场景等方面都存在差异。在实际开发中,需要根据具体的需求和设计模式来选择合适的方法来创建对象。
|
2月前
|
负载均衡 应用服务中间件 Linux
nginx学习,看这一篇就够了:下载、安装。使用:正向代理、反向代理、负载均衡。常用命令和配置文件,很全
这篇博客文章详细介绍了Nginx的下载、安装、配置以及使用,包括正向代理、反向代理、负载均衡、动静分离等高级功能,并通过具体实例讲解了如何进行配置。
180 4
nginx学习,看这一篇就够了:下载、安装。使用:正向代理、反向代理、负载均衡。常用命令和配置文件,很全
|
2月前
|
应用服务中间件 API nginx
使用正则表达式实现 Nginx 代理
【10月更文挑战第19天】在不断发展的互联网技术中,掌握正则表达式在 Nginx 代理中的应用是非常重要的。不断探索和实践,将有助于我们在实际工作中更好地运用这一技术,提升项目的质量和效率。
|
2月前
|
缓存 负载均衡 应用服务中间件
Nginx 实现一个端口代理多个前后端服务
【10月更文挑战第19天】Nginx 的强大功能不仅限于此,它还可以与其他技术和工具相结合,为我们的应用提供更强大的支持和保障。在不断发展的互联网时代,掌握 Nginx 的使用技巧将为我们的工作和生活带来更多的便利和效益。
|
2月前
|
缓存 前端开发 应用服务中间件
CORS跨域+Nginx配置、Apache配置
CORS跨域+Nginx配置、Apache配置
238 7