Closed zhaowweny closed 6 years ago
我只能保证给你demo的commit里aes和rsa的加密结果都是正确的,请求代码你也没给…不知道你用浏览器实现的话是怎么解决xhr跨域问题的…做chrome扩展?nw.js?electron?还是其他?
@nondanee 我是swift做的macOS应用,请求这块是swift做的,但是我参数用浏览器里面拿到的参数是可以正常获取数据的,换成自动生成的参数就都不行了,但是也出现过两次成功的,所以真的很困惑。给你我请求部分的代码文件。
import Foundation
struct ResultJsonDict {
var resultDict: NSMutableDictionary
}
var resultJsonDict = ResultJsonDict(resultDict: NSMutableDictionary())
class GetPostRequestUtils: NSDictionary {
var result: NSDictionary = NSDictionary()
func POST(reqUrl: String, reqArgs: String, type: String) {
let url: NSURL = NSURL(string: reqUrl)!
let request: NSMutableURLRequest = NSMutableURLRequest(url: url as URL)
//4.修改请求方法为POST
request.httpMethod = "POST"
//5.设置请求体
request.allHTTPHeaderFields = [
"Accept": "*/*",
"Accept-Language": "zh-CN,zh;q=0.8,gl;q=0.6,zh-TW;q=0.4",
"Connection": "keep-alive",
"X-Real-IP": "118.88.88.88",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "music.163.com",
"Origin": "http://music.163.com",
"Referer": "http://music.163.com",
"User-Agent": randomUserAgent()
]
request.httpBody = reqArgs.data(using: String.Encoding.utf8)
//6.根据会话对象创建一个Task(发送请求)
let (data, response, error) = URLSession.shared.synchronousDataTask(with: request as URLRequest)
var jsonStr = ""
if (networkingStatus)! {
if let error = error {
print("Synchronous task ended with error: \(error)")
jsonStr = "{\"code\":3840,\"msg\":\"\(error.localizedDescription)\"}"
var code = 0000
var msg = "发生错误"
let errorArr = "\(error)".split(separator: " ")
for errorArg in errorArr {
if (errorArg.contains("Code")) {
code = Int(((errorArg as NSString).substring(from: 6) as NSString).intValue)
print(code)
} else if (errorArg.contains("")) {
msg = String(errorArg)
print(msg)
}
}
jsonStr = "{\"code\":\(code),\"msg\":\(msg)}"
}
else {
print("Synchronous task ended without errors.呵呵呵")
do {
if let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? [String: Any] {
let jsonData: NSData = try JSONSerialization.data(withJSONObject: json, options: JSONSerialization.WritingOptions.prettyPrinted) as NSData
jsonStr = NSString(data: jsonData as Data, encoding: String.Encoding.utf8.rawValue)! as String
}
}catch{
print(error)
jsonStr = "{\"code\":3840,\"msg\":\"\(error.localizedDescription)\"}"
}
}
} else {
jsonStr = "{\"code\":404,\"msg\":\"网络连接不可用\"}"
}
resultJsonDict.resultDict.setValue(jsonStr, forKey: type)
}
}
extension URLSession {
func synchronousDataTask(with urlrequest: URLRequest) -> (Data?, URLResponse?, Error?) {
var data: Data?
var response: URLResponse?
var error: Error?
let semaphore = DispatchSemaphore(value: 0)
let dataTask = self.dataTask(with: urlrequest) {
data = $0
response = $1
error = $2
semaphore.signal()
}
dataTask.resume()
_ = semaphore.wait(timeout: .distantFuture)
return (data, response, error)
}
}
//生成随机的User Agent
func randomUserAgent() -> String {
var userAgentList = [
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36",
"Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1",
"Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1",
"Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Mobile Safari/537.36",
"Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Mobile Safari/537.36",
"Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Mobile Safari/537.36",
"Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_2 like Mac OS X) AppleWebKit/603.2.4 (KHTML, like Gecko) Mobile/14F89;GameHelper",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/603.2.4 (KHTML, like Gecko) Version/10.1.1 Safari/603.2.4",
"Mozilla/5.0 (iPhone; CPU iPhone OS 10_0 like Mac OS X) AppleWebKit/602.1.38 (KHTML, like Gecko) Version/10.0 Mobile/14A300 Safari/602.1",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:46.0) Gecko/20100101 Firefox/46.0",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:46.0) Gecko/20100101 Firefox/46.0",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)",
"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)",
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)",
"Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Win64; x64; Trident/6.0)",
"Mozilla/5.0 (Windows NT 6.3; Win64, x64; Trident/7.0; rv:11.0) like Gecko",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/13.10586",
"Mozilla/5.0 (iPad; CPU OS 10_0 like Mac OS X) AppleWebKit/602.1.38 (KHTML, like Gecko) Version/10.0 Mobile/14A300 Safari/602.1"
];
var num = Int(arc4random_uniform(UInt32(userAgentList.count)));
return userAgentList[num];
}
下面是调用的部分:
if let dic = message.body as? NSDictionary {
let params: String = (dic["params"] as AnyObject).description
let encSecKey: String = (dic["encSecKey"] as AnyObject).description
let reqArgs = "params=" + params + "&encSecKey=" + encSecKey
let reqUrl = "http://music.163.com/weapi/v3/playlist/detail?csrf_token="
let getPostRequestUtils = GetPostRequestUtils()
getPostRequestUtils.POST(reqUrl: reqUrl, reqArgs: reqArgs, type: "getPlaylistDetail")
if let jsonString = resultJsonDict.resultDict.value(forKey: "getPlaylistDetail") {
self.subWebView.evaluateJavaScript("setPlaylistDetail(\(jsonString))") { (result, error) in
if (error != nil) {
print("\(String(describing: error))")
} else if (result != nil) {
print(result as Any)
}
}
}
}
最后是js部分调用swift:
function getPlaylistDetail() {
const data = {
"id": playlistId,
"offset": 0,
"total": 1000,
"n": 1000,
"limit": 1000,
"csrf_token": ""
};
try{
webkit.messageHandlers.getPlaylistDetail.postMessage(Encrypt(data))
}catch(error){
console.error('The native context not exist ')
}
}
顺便提两个小问题,点击封面图展开歌曲列表部分希望设置一个最大高度,要不然歌单歌曲太多了,查看不方便,还有希望点击封面图后可以把这一行封面图滚动到窗口上方,如果封面图在窗口底部,那么点击后展开的部分还得滑动才能看到。最后麻烦您打包一下最新版的Mac版,上一个版本听不了歌😢谢谢!
你看看是不是reqArgs
拼两个参数前需要encodeURIComponent
在js里这样实现
var dataEncrypt = Encrypt(data)
var params = "params=" + encodeURIComponent(dataEncrypt.params) + "&encSecKey=" + encodeURIComponent(dataEncrypt.encSecKey)
webkit.messageHandlers.getPlaylistDetail.postMessage(params)
UI是参照Groove Music做的,以后也不大会改 主要是传包要等好久,所以懒着打了😂等等去打一下
@nondanee 果然是要用encodeURIComponent处理一下🤣🤣🤣困扰我好长时间了,非常感谢,不过不明白就是一个字符串参数怎么还要处理。。。可能是swift请求部分处理参数了,所以导致发出去的参数不对。
我这什么API都拿不到数据,偶尔两次拿到歌单信息😅