tvos - 在 TVML 应用程序中更改 XMLHttpRequest 的用户代理

标签 tvos apple-tv tvjs

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

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

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

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

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

最佳答案

在花了两天时间调查这个问题后,我找到了解决方案,方法是快速创建 native GETPOST 方法,最终将它们暴露给 javascript。这不是最佳解决方案,但我仍然想分享它。也许它可以帮助某人。

它是如何工作的

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

Readme on github has all instructions you need to install it

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

import Alamofire

然后我们需要在应用程序 Controller (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");
}

Full code of AppDelegate.swift you can find here

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

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

这是它在 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);
    });
}

The code above is written in ES6 and you'll need to include Promise polifill in your TVJS app.

现在我们可以发出 GETPOST 请求,应用我们需要的任何 header

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

关于tvos - 在 TVML 应用程序中更改 XMLHttpRequest 的用户代理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33701867/

相关文章:

web - Apple TV 用户代理字符串。任何人都可以提供吗?

xcode - 如何创建 React-Native tvos 项目?

javascript - 使用 XMLHttpRequest 为 RGB 图像生成主色

ios - NSURL 请求不起作用

swift - 当单元格聚焦时无法更改 subview 的 alpha

json - 在 swift 中下载 JSON 数据并对其进行排序

avplayer - 以编程方式减少 Apple TV 上的大声

swift - 应用程序未在 tvOS 10 Beta 上运行

javascript - TVML 创建动态模板