You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何重写Backbone.ajax方法以使用cordova-plugin-advanced-HTTP?

解决Backbone.js + PhoneGap中CORS Origin问题:用cordova-plugin-advanced-HTTP重写Backbone.ajax

你遇到的核心问题是浏览器的同源策略安全限制——浏览器不允许手动修改Origin这类敏感请求头,所以只能通过原生插件绕过,因为插件的请求是在原生层发起的,不受浏览器CORS规则约束。下面是完整的重写方案:

步骤1:确认插件已安装

先确保你已经正确安装了cordova-plugin-advanced-HTTP:

cordova plugin add cordova-plugin-advanced-HTTP

步骤2:重写Backbone.ajax方法

我们需要把Backbone默认的jQuery Ajax调用替换成插件API,同时保持Backbone期望的Deferred/Promise接口一致,这样现有Model/Collection的fetch()save()等方法无需修改就能正常工作:

Backbone.ajax = function(options) {
    // 创建jQuery Deferred对象,保持和Backbone原生Ajax的Promise兼容
    const deferred = Backbone.$.Deferred();
    
    // 整理插件所需的参数
    const httpOptions = {
        url: options.url,
        headers: options.headers || { 'Accept': 'application/json' },
        data: options.data || {}
    };

    // 处理不同HTTP请求方法
    switch(options.method?.toUpperCase() || 'GET') {
        case 'GET':
            cordova.plugin.http.get(
                httpOptions.url,
                httpOptions.data,
                httpOptions.headers,
                (response) => {
                    // 尝试解析JSON响应,兼容非JSON场景
                    try {
                        response.data = JSON.parse(response.data);
                    } catch(e) {}
                    deferred.resolve(response);
                },
                (error) => {
                    // 统一错误格式,适配Backbone的错误处理逻辑
                    deferred.reject({
                        status: error.status,
                        responseText: error.error,
                        responseJSON: error.data ? JSON.parse(error.data) : null
                    });
                }
            );
            break;
        
        case 'POST':
            // 默认设置JSON格式的Content-Type,可根据后端需求调整
            if (!httpOptions.headers['Content-Type']) {
                httpOptions.headers['Content-Type'] = 'application/json';
                httpOptions.data = JSON.stringify(httpOptions.data);
            }
            cordova.plugin.http.post(
                httpOptions.url,
                httpOptions.data,
                httpOptions.headers,
                (response) => {
                    try {
                        response.data = JSON.parse(response.data);
                    } catch(e) {}
                    deferred.resolve(response);
                },
                (error) => {
                    deferred.reject({
                        status: error.status,
                        responseText: error.error,
                        responseJSON: error.data ? JSON.parse(error.data) : null
                    });
                }
            );
            break;
        
        // 按需扩展PUT、DELETE等方法
        case 'PUT':
            if (!httpOptions.headers['Content-Type']) {
                httpOptions.headers['Content-Type'] = 'application/json';
                httpOptions.data = JSON.stringify(httpOptions.data);
            }
            cordova.plugin.http.put(
                httpOptions.url,
                httpOptions.data,
                httpOptions.headers,
                (response) => {
                    try {
                        response.data = JSON.parse(response.data);
                    } catch(e) {}
                    deferred.resolve(response);
                },
                (error) => {
                    deferred.reject({
                        status: error.status,
                        responseText: error.error,
                        responseJSON: error.data ? JSON.parse(error.data) : null
                    });
                }
            );
            break;
        
        case 'DELETE':
            cordova.plugin.http.delete(
                httpOptions.url,
                httpOptions.data,
                httpOptions.headers,
                (response) => {
                    try {
                        response.data = JSON.parse(response.data);
                    } catch(e) {}
                    deferred.resolve(response);
                },
                (error) => {
                    deferred.reject({
                        status: error.status,
                        responseText: error.error,
                        responseJSON: error.data ? JSON.parse(error.data) : null
                    });
                }
            );
            break;
        
        default:
            deferred.reject(new Error(`Unsupported HTTP method: ${options.method}`));
    }

    // 返回Deferred的Promise,保持接口一致性
    return deferred.promise();
};

关键细节说明

  1. 接口兼容:用jQuery的Deferred封装插件的回调,确保现有代码里的done()fail()或者async/await逻辑无需修改。
  2. 请求头与序列化:默认配置JSON格式的请求头和序列化逻辑,如果你的后端需要表单格式,只需修改Content-Type并去掉JSON.stringify即可。
  3. 错误统一:把插件返回的错误格式转换成Backbone熟悉的结构,避免现有错误处理逻辑崩溃。
  4. 执行时机:这段重写代码要在deviceready事件触发后执行,确保cordova.plugin.http对象已经初始化完成。

内容的提问来源于stack exchange,提问作者Sreekanth

火山引擎 最新活动