返回

解决Vue.js应用跨设备API访问失败:网络错误排查指南

vue.js

解决 Vue.js 应用中跨设备访问后端 API 失败的问题

在开发过程中,常常会遇到前端应用能够在本机正常访问后端 API,但在其他设备上却出现网络错误的问题。这类问题多半由跨域、IP 地址配置、端口映射以及防火墙等因素引起。

问题分析

根据提供的案例,当从本机访问 Vue 应用时,前端与后端的通信工作正常。 但当尝试从其他设备访问时,就会出现 Network Error。 此错误在浏览器控制台中通常被记录为 AxiosError: Network Error。这表明 Vue 应用发送的网络请求无法到达后端 API,连接请求超时或被拒绝。

问题的根源可能包含以下几点:

  1. 后端服务监听地址: 后端 Express 服务器可能只监听了 localhost 或者 127.0.0.1,而没有监听本机 IP。导致其他设备无法通过 IP 地址访问到。

  2. 前端配置的 API 地址: 前端代码中的 baseURL 可能硬编码为了 localhost 或者 127.0.0.1。 这样当在其他设备访问前端应用时,它仍然尝试连接本地 IP,导致无法找到对应的后端服务。

  3. CORS (跨域资源共享): 浏览器具有安全机制,当你的前端应用和后端 API 的来源不一致(协议、域名、端口不同)时,可能会触发 CORS 限制。

  4. 防火墙拦截: 设备上的防火墙可能会拦截从其他网络设备发出的访问请求,导致连接失败。

  5. 网络连接问题 其他设备可能由于各种网络原因无法和宿主机建立连接。

  6. 路由的影响 (初步排除): 虽然在问题中提到了 vue-router 模块的加入,但该模块主要处理前端路由跳转,它本身并不会直接导致后端请求的失败。真正问题往往出在请求的目标地址无法正常访问后端服务。

解决方案

下面将提供一系列解决方案,帮助你排除并修复这类问题。

方案一:配置后端服务监听所有 IP

  1. 问题: Express 服务器监听了 localhost127.0.0.1

  2. 原因: 默认情况下, Express 服务器绑定 127.0.0.1 ,这表示服务器仅响应来自同一台机器的请求。 这时候通过局域网其他机器的IP访问则无法触达。

  3. 解决方法: 修改 Node.js 的 Express 应用的 app.listen 调用,将其绑定的 IP 地址设置为 0.0.0.0。这表示服务器将监听所有可用的网络接口。

  4. 操作步骤和代码示例:

    修改 index.js 文件中的 app.listen 调用:

     const port = 48000
        // 把原来的
        //app.listen(
        //    port,
        //    () => {console.log('Listening PORT')}
        // )
        // 改为:
    app.listen(
            port,
            '0.0.0.0',
            () => {console.log('Listening PORT')}
         )
    

这一操作告诉你的后端服务,它应接收任何源自本地机器上网络端口为 48000 的网络流量, 包括那些通过 IP 地址从局域网的其他设备上发起。

**补充说明:**  如果你不设置或者不指定ip,express默认会绑定 `127.0.0.1`

方案二:调整前端 API 地址配置

  1. 问题: Vue 应用中 baseURL 硬编码为本地地址 localhost 或特定 IP,其他设备无法解析到服务器的地址。

  2. 原因: 如果axios.create 设置的baseURL是明确ip地址或者localhost,其他设备将无法正确路由访问后端的服务器

  3. 解决方法: 在开发环境可以使用IP, 但正式部署时可以使用动态配置。比如你可以在前端 Vue 应用启动时动态获取后端 API 地址,也可以在前端配置一个相对地址。 例如,你可以配置 baseURL 为相对路径(例如/api),然后使用 Vue 的代理功能将请求转发到实际的后端地址。

  4. 操作步骤和代码示例:

    首先,修改 Vue 中的 ax配置。 例如,你可以在.env或者一个 config.js中定义 API地址。然后在环境变量中或者config读取:
    .env:

    VITE_API_BASE_URL=http://10.109.142.233:48000
    
    // TestPage.vue
    
    import axios from 'axios';
    
    const apiBaseURL = import.meta.env.VITE_API_BASE_URL
    
    axios.defaults.headers.common = {
        "Content-Type": "application/json"
    }
    const ax = axios.create({
        baseURL: apiBaseURL  
    })
    ax.defaults.headers = {
        "Content-Type": "application/json"
    }
    
    
  5. 使用 Vite 代理 :在项目 vite.config.js配置 proxy:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  server: {
    proxy: {
      '/api': { // 使用 /api 开头的请求会被转发到后端服务
        target: 'http://10.109.142.233:48000',  //  改成你后端的ip地址和端口号
        changeOrigin: true, // needed for virtual hosted sites
         secure:false // 如果后端的服务器不支持SSL/HTTPS
      },
     }
   }
})

此时,axios.createbaseURL 应设置为 /api


    import axios from 'axios';

    axios.defaults.headers.common = {
        "Content-Type": "application/json"
    }
    const ax = axios.create({
        baseURL: '/api'  
    })
    ax.defaults.headers = {
        "Content-Type": "application/json"
    }

方案三:配置 CORS

  1. 问题: 浏览器因为跨域限制阻止前端应用请求后端 API

  2. 原因: 当前端应用和后端 API 部署在不同的域名或端口上时,会遇到跨域请求的限制。

  3. 解决方法: 在 Express 中添加 cors 中间件,允许跨域请求。 可以控制来自不同来源的网络访问请求。

  4. 操作步骤和代码示例:
    安装 cors: npm install cors

    在 Express 代码中使用 cors 中间件,你可以指定可接受的请求来源

     // index.js
     const express = require('express')
     const bodyParser = require('body-parser')
     const cors = require('cors')

     // 修改此项,指定特定的来源 或者 *
    const corsOptions = {
       origin: 'http://10.109.142.233:8080', //只允许来自这个地址访问
       //或者origin:'*' 表示所有来源的请求都被允许访问
       optionsSuccessStatus: 200 // 一些旧的浏览器(IE11, Safari)响应204导致一些问题,设置成功响应状态为200,来确保成功响应
     }
     const port = 48000
     const app = express()
     app.use(bodyParser.urlencoded({
         extended: true
     }));
     app.use(bodyParser.json())
    // 在路由前配置 CORS 中间件,设置允许的域名
     app.use(cors(corsOptions))

     // ... 后面的代码不更改

注意 在生产环境中, 请将 'http://10.109.142.233:8080' 修改为你的真实域名。 origin: '*'表示允许来自所有来源的访问请求, 不建议在生产环境使用,因为它带来安全隐患。

方案四:检查防火墙设置

  1. 问题: 其他设备请求可能被防火墙拦截
  2. 原因: 设备防火墙会默认阻止外部设备的访问。
  3. 解决方法: 确保后端服务器设备(通常也是运行 Vue 应用的设备)的防火墙允许来自局域网的流量通过你配置的端口。 你可以在 Windows 防火墙设置里或者其它安全软件,开放 TCP 端口 48000 。

额外的安全建议

  1. 在生产环境中,避免使用0.0.0.0监听, 应考虑设置绑定本地内网IP, 使用nginx之类的代理进行流量转发,可以进一步增强应用的安全性。
  2. 请始终避免直接将任何个人信息, 例如token,密码硬编码进你的代码, 而是使用配置环境变量的方式加载配置项
  3. 为你的应用程序开启https。 这对用户敏感数据的保护很重要,并且是一个更好的开发习惯。

通过以上步骤,你应该能够定位并解决前端 Vue 应用无法从其他设备访问后端 API 的问题。请记住,网络问题可能涉及多种因素,在遇到困难时请逐步排查、逐个解决。