已經被傷害的無法自拔,不然週末也不會苦逼的在這加班,說說問題的來源。最近在研究html5.想要從喜馬拉雅那邊獲取到他們的點播接口。就在我把sig和aceess_token算好了之後就被這個同源策略給坑的不行。
先把我的url地址放上來:
(http://api.ximalaya.com/categories/list?app_key=b90545b0ff18ac24bc6c10fd7bcb9fa3&client_os_type=3&
device_id=mybeb&pack_id=com.video&access_token=e907ca4a6b36c15af6d0ad9963b29513&sig=9a22323ab2f4e87e63b395b0492ac9dd)
然後按照平常的思路,只知道一個url地址想要取到裏面的json數據當然就是js裏面的ajax。
所以代碼就來了:
法1:
function loadXMLDoc() {
- //1.創建XMLHttpRequest對象
- //這是XMLHttpReuquest對象無部使用中最複雜的一步
- //需要針對IE和其他類型的瀏覽器建立這個對象的不同方式寫不同的代碼
然後運行之後瀏覽器就來了這樣一個東西。好吧就是同源策略。
然後啓用firebug在網絡裏面查到的就是這個鬼,完全被攔截了好嗎,json數據就出不來?
然後就去找同源策略的相關解決辦法,看了一下大概有一下幾種:
1.把兩個地址改在同一個域名下,反正域名這東西我一直不太懂,但是顯然不適合我這個,我就一個html5文件,運行出來肯定是localhost啦,不知道怎麼改。
2.加一個響應頭;Access-Control-Origin,這個響應頭要在服務器那端加,改服務器代碼肯定是不可能的,又不是我的。
3.好像是所謂的window.postmessage()方法,沒怎麼看懂,不過按照案例試了一下game over。
法2:就是用jquery然後用jsonp的方式:
$(function(){
$.ajax({
async: false,
type: "GET",
dataType: 'jsonp',
jsonp: 'callback',
jsonpCallback: 'callbackfunction',
url: "http://api.ximalaya.com/categories/list?app_key=b90545b0ff18ac24bc6c10fd7bcb9fa3&client_os_type=3&" +
"device_id=mybeb&pack_id=com.video&access_token=f299e2d8e4cf8f0c43d80854d0f6e364&sig=b880936cead04e026c4ba0b0f89cb86e",
data:"",
timeout: 3000,
contentType: "application/json;utf-8",
success: function(msg) {
console.log(msg);
}
});
})
倒是沒有同源策略了。那麼問題又來了;400錯誤:請求地址不存在或者包含不支持的參數 地址和參數肯定都是在的。
這樣倒是有Json數據了,可是呢報101錯誤呀 signature check failed 簽名驗證失敗,然後我又陷入了無限的循壞中,sig算了不下十遍,一個appkey算怕出錯,又算了一個,算到自己都不知到再算什麼了。
後來又想會不會是這個地址不支持用jsonp呢,畢竟不是官方發佈的。
法3:這次採用了代理服務器。就是yahoo的那個;
這次可以啦,只是用代理會減慢請求速率,並且還將希望寄託在他人服務器上,必須得保證他人服務器不崩潰,有一定侷限性。
法4:內嵌一個script 然後通過回調函數。
var callbackfunction = function(data) {
console.log('我是跨域請求來的數據-->' + data.name);
};
var script = document.createElement('script'),
body = document.getElementsByTagName('body');
script.src ='http://api.ximalaya.com/categories/list?app_key=b90545b0ff18ac24bc6c10fd7bcb9fa3&client_os_type=3&' +
'device_id=mybeb&pack_id=com.video&access_token=e907ca4a6b36c15af6d0ad9963b29513&sig=9a22323ab2f4e87e63b395b0492ac9dd?callback=callbackfunction';
body[0].appendChild(script);
這次也解決啦;只是,最後法1,2,3,4都沒有采用,採用的是node.js啦。比上面的幾種辦法要好點;
這裏也附上代碼:
'use strict';
var http=require("http");
var request =require("request");
var server=http.createServer(function(req,res){
if(req.url!=="/favicon.ico"){
request.post({url: 'http://api.ximalaya.com/oauth2/secure_access_token', timeout: 3000, form: {client_id:'8a6ac9fa6af234963329f674d3513f95',device_id:'myweb',grant_type:'client_credentials',nonce:'7abe3tsfef',timestamp:'1453116822556',sig:'cab74d75d8744ad331c0283b0a18964d'}},
function (error, response, data) {
if (!error && response.statusCode == 200) {
console.log(data);
} else {
console.log(data);
}
res.statusCode=200;
res.sendDate=true;
res.setHeader("Content-Type","text/plain");
res.setHeader("Access-Control-Allow-Origin","*");
res.write(data.toString());
res.end();
});
}
});
server.listen(1053,"localhost",function(){
console.log("開始監聽...");
});