一、jsonp
JSONP包含两部分:回调函数和数据。
回调函数是当响应到来时要放在当前页面被调用的函数。
数据就是传入回调函数中的json数据,也就是回调函数的参数了。
function handleResponse(response){
console.log('The responsed data is: '+response.data);
}
var script = document.createElement('script');
script.src = 'http://www.baidu.com/json/?callback=handleResponse';
document.body.insertBefore(script, document.body.firstChild);
/*handleResonse({"data": "zhe"})*/
//原理如下:
//当我们通过script标签请求时
//后台就会根据相应的参数(json,handleResponse)
//来生成相应的json数据(handleResponse({"data": "zhe"}))
//最后这个返回的json数据(代码)就会被放在当前js文件中被执行
//至此跨域通信完成
jsonp虽然很简单,但是有如下缺点:
- jsonp只能用于执行跨域
get
请求 - 服务器必须支持jsonp
- 安全问题(请求代码中可能存在安全隐患)
二、CORS(Cross-Origin Resource Sharing)
跨域资源共享(CORS) 是一种机制,它使用额外的 HTTP 头来告诉浏览器 让运行在一个 origin (domain) 上的Web应用被准许访问来自不同源服务器上的指定的资源。
例子:
origin 3001中的服务器检查此来源是否可以访问数据,并使用附加的Access-Control-Allow-Origin
头(列出请求的来源)增加响应:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://localhost:3000
Content-Type: application/json; charset=utf-8
Content-Length: 62
{
"response": "This is data returned from the CORS server"
}
出于安全原因,浏览器限制从脚本内发起的跨源HTTP请求。 例如,XMLHttpRequest和Fetch API遵循同源策略。 这意味着使用这些API的Web应用程序只能从加载应用程序的同一个域请求HTTP资源,除非响应报文包含了正确CORS响应头。
(译者注:这段描述不准确,并不一定是浏览器限制了发起跨站请求,也可能是跨站请求可以正常发起,但是返回结果被浏览器拦截了。)
三、服务端代理(略)
各个方案对比
MECHANISM | SUPPORTED HTTP VERBS | SERVER-SIDE MODIFICATIONS REQUIRED? | REMARKS |
---|---|---|---|
JSONP | GET | Yes (return script block containing function call instead of raw JSON) | Requires absolute trust in the server |
Proxy | ALL | No (but you need an extra proxy component in your origin) | Back-end performs the request instead of the browser. Could prove problematic for authentication |
CORS | ALL | Yes (return additional HTTP headers) | Not supported on older versions of Internet Explorer. For “complex” requests, needs to make an extra HTTP call (preflighted requests). Some firewalls strip CORS headers. |