已经被伤害的无法自拔,不然周末也不会苦逼的在这加班,说说问题的来源。最近在研究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("开始监听...");
});