欢迎光临韵绾网
详情描述

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中配置代理

注意事项

  • 浏览器对CORS的支持:现代浏览器都支持,但IE10以下需要额外处理
  • 复杂的CORS请求会触发预检请求(OPTIONS)
  • 确保服务器正确配置CORS头部
  • 考虑HTTPS协议的跨域限制
相关帖子
南阳市公司注册资本变更办理流程-中小微企业注册,专业代办服务,收费合理
南阳市公司注册资本变更办理流程-中小微企业注册,专业代办服务,收费合理
文化中的蝙蝠意象:从福寿象征到西方吸血鬼传说演变
文化中的蝙蝠意象:从福寿象征到西方吸血鬼传说演变
南阳市ICP经营许可证办理|公司注册代办,全程代办,这里靠谱
南阳市ICP经营许可证办理|公司注册代办,全程代办,这里靠谱
南阳市工商解非-注册公司费用及流程,无需法人到场
南阳市工商解非-注册公司费用及流程,无需法人到场
南阳市工商年检-个体户营业执照代办,全程代办,收费合理
南阳市工商年检-个体户营业执照代办,全程代办,收费合理
镇海区网站建设本地公司@AI数字人制作短视频,提供一站式建站服务
镇海区网站建设本地公司@AI数字人制作短视频,提供一站式建站服务
大风、暴雨、暴雪等不同颜色的预警,对应的停工停课标准是怎样的?
大风、暴雨、暴雪等不同颜色的预警,对应的停工停课标准是怎样的?
Windows Server 2025 安装AD CS角色和颁发证书
Windows Server 2025 安装AD CS角色和颁发证书
普洱市商标注册|股份有限公司注册,正规代办公司
普洱市商标注册|股份有限公司注册,正规代办公司
成都市食品卫生许可证办理电话-个体户注册,不成功不收费,专业代办
成都市食品卫生许可证办理电话-个体户注册,不成功不收费,专业代办
镇江市公司注册资本变更办理-公司注册服务,24小时在线,欢迎电话咨询
镇江市公司注册资本变更办理-公司注册服务,24小时在线,欢迎电话咨询
鹤壁市品牌网站建设公司@小视频营销推广,多年建站经验
鹤壁市品牌网站建设公司@小视频营销推广,多年建站经验
Nginx之https证书配置实现
Nginx之https证书配置实现
SQL中表的字符串内置函数详解
SQL中表的字符串内置函数详解
遭遇理发店、健身房老板跑路,卡里余额该如何有效维权和追讨?
遭遇理发店、健身房老板跑路,卡里余额该如何有效维权和追讨?
2026年考取哪些新兴行业的职业资格证书可以申请技能提升补贴?
2026年考取哪些新兴行业的职业资格证书可以申请技能提升补贴?
Pandas基础使用指南之排序、字符串日期处理和文件合并拆分技巧
Pandas基础使用指南之排序、字符串日期处理和文件合并拆分技巧
2026年农村五保户的供养补助标准是否有新的调整,大概是多少?
2026年农村五保户的供养补助标准是否有新的调整,大概是多少?
鹰潭市python开源商城二次开发@做网站,定制开发
鹰潭市python开源商城二次开发@做网站,定制开发
Solaris10如何更改子网掩码?Solaris10更改子网掩码的方法
Solaris10如何更改子网掩码?Solaris10更改子网掩码的方法