在项目中遇到错误提示“No 'Access-Control-Allow-Origin' header is present on the requested resource.”查了下度娘,这个问题和安全机制有关,默认不允许跨域调用,这里记录一下解决方案,防止以后再犯相同的错误。
调用web接口,get请求,发现提示:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
这个和安全机制有关,默认不允许跨域调用
处理手段:使用jsonp格式, ajax请求参数dataType:'JSONP'。
复制代码 代码如下:
$.ajax({
url: "http://.......",
type: 'GET',
dataType: 'JSONP',//here
success: function (data) {
}
});
最近工作中用到jsonp是为了解决ajax的跨域获取数据问题
举个栗子
前端页面http://a.com/1.html中的js向服务器http://b.com/2.php获取数据,如果用普通的ajax方式,会被浏览器认为是跨域不安全而拦截,这个时候就需要使用jsonp了,相应的前后端代码都要做一些改动
下面以jquery框架为例,jquery提供了getJSON方法来实现jsonp,这个时候你需要在请求的url后面加上“callback=?”,上面的例子就是 http://b.com/2.php?callback=?。
然后其实jquery会在getJSON方法被触发时,动态的创建一个script,这个script的src会是类似于http://b.com/2.php?callback=jsonp1339589075417这种形式,也就是jquery会自动以某个值替换=?中的问号。这样的话,浏览器发现新来了一个script,就会向src指定的url请求数据。
然后服务器端2.php需要做的是获取到callback的值,然后把你的本来要返回的json格式数据包装成如下格式:
jsonp1339589075417({"key1":"value1", "key2":"value2"})
也就是在原先的json数据前后加半边括号,并且在前括号前再加上callback的值。
JSONP的用处是:跨域资源共享(Resources Domain Resources Sharing),客户端从不同的域名发送JSON响应时绕过浏览器限制。
为了解释清楚,来看JSON和JSONP的对比:
JSON(JavaScript Object Notation)是在应用间传输数据的方式,常用于JavaScript目标应用。
jQuery可以从一个脚本对服务器发出Ajax/HTTPD调用,$.getJSON()可以获取服务响应。
但是当网页的ajax调用存在于服务器不同的域名中时,这种方法可能会失败。在某些浏览器中,出于安全,同源策略(Same Origin Policy)禁止了跨域名调用。
比如:早期的Chrome24和Firefox17没有这种限制,而IE9则有这种限制(同源策略)。开发者们,想在所有浏览器中解除这种安全限制。
JSONP(JSON with Padding)就是为了让所有浏览器都能够跨域名调用。
JSONP将JSON请求封装进一个JavaScript函数,作为脚本发回给浏览器。客户端加载时,该脚本不受限于同源策略,函数就像其中的JSON对象一样。
示例:
JSON:
服务器:
get '/json' do content_type :json content = { :response => 'Sent via JSON', :timestamp => Time.now, :random => rand(10000) } content.to_json end
客户端:
var url = host_prefix + '/json'; $.getJSON(url, function(json){ $("#json-response").html(JSON.stringify(json, null, 2)); });
JSON响应:
{ "response": "Sent via JSON", "timestamp": "2016-10-04 02:52:33 +0000", "random": 2698 }
用JSON传输服务器响应。客户端用jQuery函数$.getJSON发出一个ajax请求。服务器生成一个hash,将其格式化成JSON,然后返回给客户端。客户端将其格式化后,放进网页元素中。
JSONP:
服务器:
get '/jsonp' do callback = params['callback'] content_type :js content = { :response => 'Sent via JSONP', :timestamp => Time.now, :random => rand(10000) } "#{callback}(#{content.to_json})" end
客户端:
var url = host_prefix + '/jsonp?callback=?'; $.getJSON(url, function(jsonp){ $("#jsonp-response").html(JSON.stringify(jsonp, null, 2)); });
JSONP响应:
{ "response": "Sent via JSONP", "timestamp": "2016-10-04 02:52:51 +0000", "random": 675 }
客户端的JSONP向URL添加了一个回调参数(callback parameter),也就是说'callback=?',在这种情况下,jQuery会生成唯一的函数名,然后传送给服务器。
在服务器,不是直接返回原始JSON,而是将这个回调参数的字符串放到函数定义中,比如"()"。开发者不需要预先知道函数名,只要回调参数就行了。
回到客户端,返回的函数就像原始JSON对象一样。