【问题标题】:Change User-Agent for XMLHttpRequest in TVML app在 TVML 应用程序中更改 XMLHttpRequest 的用户代理
【发布时间】:2015-11-13 21:14:45
【问题描述】:

我正在使用 TVMLKit 开发 Apple TV 应用程序。我的应用程序的 JavaScript 代码尝试使用 XMLHttpRequest 向服务器发送 HTTP 请求。服务器需要一个特定的用户代理,所以我尝试了这个:

var request = new XMLHttpRequest();
request.open("GET", url, true);
request.setRequestHeader("User-Agent", "MyApp");
request.send();

服务器收到不同的 User-Agent 标头:

User-Agent: <Projectname>/1 CFNetwork/758.1.6 Darwin/15.0.0

如果我将标头名称更改为不同的名称,它会显示在请求标头中。我猜 Apple 在发送请求之前正在替换 User-Agent 字段。有没有办法防止这种情况发生?

【问题讨论】:

  • 昨天遇到了同样的问题。似乎Apple使用浏览器的实现并禁止将某些标头设置为User-Agent

标签: tvos apple-tv tvjs


【解决方案1】:

在花了两天时间调查这个问题之后,我找到了解决方案,即在 swift end 中创建原生 GETPOST 方法,将它们暴露给 javascript。这不是最好的解决方案,但我仍然想分享它。也许它可以帮助某人。

这里是如何工作的

首先我们需要安装Alamofire 库。我们将使用它来创建请求。

github 上的自述文件包含安装它所需的所有说明

安装Alamofire后我们需要将其导入AppDelegate.swift

import Alamofire

然后我们需要在应用控制器 (AppDelegate.swift) 中创建函数,将方法暴露给 javascript

func appController(appController: TVApplicationController, evaluateAppJavaScriptInContext jsContext: JSContext)
{
    let requests = [String : AnyObject]()

    let get: @convention(block) (String, String, [String : String]?) -> Void = { (cId:String, url:String, headers:[String : String]?) in

        Alamofire.request(.GET, url, headers: headers)
            .responseString { response in
                jsContext.evaluateScript("requests." + cId + "(" + response.result.value! + ")")
        }
    }

    let post: @convention(block) (String, String, [String : AnyObject]?, [String : String]?) -> Void = { (cId:String, url:String, parameters:[String : AnyObject]?, headers:[String : String]?) in

        Alamofire.request(.POST, url, parameters: parameters, headers: headers)
            .responseString { response in
                jsContext.evaluateScript("requests." + cId + "(" + response.result.value! + ")")
        }
    }

    jsContext.setObject(requests, forKeyedSubscript: "requests");
    jsContext.setObject(unsafeBitCast(get, AnyObject.self), forKeyedSubscript: "nativeGET");
    jsContext.setObject(unsafeBitCast(post, AnyObject.self), forKeyedSubscript: "nativePOST");
}

AppDelegate.swift的完整代码你可以找到here

一切就绪!现在我们可以通过 javascript 访问 nativeGETnativePOST 函数了。

最后一件事是发出请求并检索响应。我不明白如何在 swift 中进行回调执行,所以我使用了 jsonp 方法,使用运行时生成的函数并将它们的名称传递给本机函数。

这是它在 javascript 中的样子

export function get(url, headers = {}) {
    return new Promise((resolve) => {
        const cId = `get${Date.now()}`;
        requests[cId] = response => {
            delete requests[cId];
            resolve(response);
        }
        nativeGET(cId, url, headers);
    });
}

export function post(url, parameters = {}, headers = {}) {
    return new Promise((resolve) => {
        const cId = `post${Date.now()}`;
        requests[cId] = response => {
            delete requests[cId];
            resolve(response);
        }
        nativePOST(cId, url, parameters, headers);
    });
}

上面的代码是用 ES6 编写的,你需要在你的 TVJS 应用中包含Promisepolifill。

现在我们可以使用我们需要的任何标头发出 GETPOST 请求

post('http://example.com/', {
    login: 'xxx', 
    password: 'yyy'
}, {
    'User-Agent': 'My custom User-Agent'
})

【讨论】:

    猜你喜欢
    • 2014-02-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-15
    • 1970-01-01
    • 2010-10-03
    • 1970-01-01
    • 1970-01-01
    • 2015-07-07
    相关资源
    最近更新 更多