南阳市文章资讯

AJAX跨域请求获取JSON数据的实现方法

2026-03-25 21:54:01 浏览次数:0
详细信息

AJAX跨域请求获取JSON数据主要有以下几种实现方法:

1. CORS(跨域资源共享)【推荐】

服务器端设置响应头允许跨域访问:

// 服务器端示例(Node.js)
app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*'); // 允许所有域名
  // 或指定域名
  // res.header('Access-Control-Allow-Origin', 'https://example.com');
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
  res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  next();
});

客户端正常使用AJAX:

// 前端请求
fetch('https://api.example.com/data', {
  method: 'GET',
  headers: {
    'Content-Type': 'application/json'
  }
})
.then(response => response.json())
.then(data => console.log(data));

2. JSONP(仅限GET请求)

function jsonp(url, callback) {
  const callbackName = 'jsonp_callback_' + Math.random().toString(36).substr(2);

  window[callbackName] = function(data) {
    delete window[callbackName];
    document.body.removeChild(script);
    callback(data);
  };

  const script = document.createElement('script');
  script.src = url + (url.includes('?') ? '&' : '?') + 'callback=' + callbackName;
  document.body.appendChild(script);
}

// 使用
jsonp('https://api.example.com/data?param=value', function(data) {
  console.log('获取到的数据:', data);
});

3. 服务器端代理

在自己的服务器上创建代理接口:

// Node.js Express 代理示例
const express = require('express');
const axios = require('axios');
const app = express();

app.get('/api/proxy', async (req, res) => {
  try {
    const response = await axios.get('https://api.example.com/data', {
      params: req.query
    });
    res.json(response.data);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

app.listen(3000);

前端调用自己的代理接口:

fetch('/api/proxy?param=value')
  .then(response => response.json())
  .then(data => console.log(data));

4. 使用现代JavaScript库

使用Axios:

import axios from 'axios';

// 配置默认设置
axios.defaults.headers.common['Content-Type'] = 'application/json';

// 简单请求
axios.get('https://api.example.com/data')
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.error('请求失败:', error);
  });

// 带配置的请求
axios.get('https://api.example.com/data', {
  headers: {
    'Authorization': 'Bearer token'
  },
  params: {
    page: 1,
    limit: 10
  }
});

使用jQuery:

$.ajax({
  url: 'https://api.example.com/data',
  type: 'GET',
  dataType: 'json',
  crossDomain: true,
  headers: {
    'Accept': 'application/json'
  },
  success: function(data) {
    console.log('成功:', data);
  },
  error: function(xhr, status, error) {
    console.error('失败:', error);
  }
});

5. 处理预检请求(Preflight)

对于复杂请求(如带自定义头或非简单方法),需要处理OPTIONS预检请求:

// 服务器端处理预检请求
app.options('*', (req, res) => {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
  res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With');
  res.sendStatus(200);
});

6. 带凭据的请求(Cookies/Authentication)

// 客户端
fetch('https://api.example.com/data', {
  credentials: 'include', // 发送cookies
  headers: {
    'Authorization': 'Bearer ' + token
  }
});

// 服务器端
res.header('Access-Control-Allow-Credentials', 'true');
res.header('Access-Control-Allow-Origin', 'https://yourdomain.com'); // 不能使用*

7. 封装通用的跨域请求函数

class ApiClient {
  constructor(baseURL) {
    this.baseURL = baseURL;
  }

  async request(endpoint, options = {}) {
    const url = `${this.baseURL}${endpoint}`;
    const defaultOptions = {
      headers: {
        'Content-Type': 'application/json',
      },
      mode: 'cors',
      credentials: 'same-origin', // 或 'include'
    };

    try {
      const response = await fetch(url, {
        ...defaultOptions,
        ...options,
        headers: {
          ...defaultOptions.headers,
          ...options.headers,
        },
      });

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }

      return await response.json();
    } catch (error) {
      console.error('请求失败:', error);
      throw error;
    }
  }

  get(endpoint, params = {}) {
    const queryString = new URLSearchParams(params).toString();
    const url = queryString ? `${endpoint}?${queryString}` : endpoint;
    return this.request(url, { method: 'GET' });
  }

  post(endpoint, data) {
    return this.request(endpoint, {
      method: 'POST',
      body: JSON.stringify(data),
    });
  }
}

// 使用
const api = new ApiClient('https://api.example.com');
api.get('/data', { page: 1, limit: 10 })
  .then(data => console.log(data));

最佳实践建议

优先使用CORS:这是W3C标准,支持所有HTTP方法 生产环境限制源:避免使用通配符*,指定允许的域名 安全性考虑:验证请求来源,使用适当的认证机制 错误处理:添加完善的错误处理逻辑 性能优化:考虑缓存策略,减少不必要的请求 考虑使用反向代理:在Nginx或Apache中配置代理

注意事项

相关推荐