ajax使用api和CORS以及JSONP(CORS+JSONP
2018-09-20 本文已影响1人
不知道取个什么昵称不如娶个媳妇
在使用ajax的时候存在一个问题:
相同域名下从后端获取数据是可以直接来获取的,而如果域名不相同,就会存在无法访问问题,浏览器会禁止这种跨域行为
这是因为浏览器的安全策略,保障非同源资源间数据访问的安全问题。默认非同源资源间不能直接访问。
URL的结构:
协议://域名:端口/资源路径?查询字符串#hash
协议、域名、端口完全一致,表示同源,只要有任何一个不一致,则是非同源的资源。
非同源资源间的访问称作跨域资源访问。
那么如何解决这种问题呢?
方法一 CORS
Cross-Origin Resource Sharing
http://www.ruanyifeng.com/blog/2016/04/cors.html
服务器端(后端):
必须设置响应头信息:"Access-Control-Allow-Origin:*"
可选:Access-Control-Allow-Methods(允许请求的方式)
客户端(前端):
ajax(利用新版本的XMLHttpRequest功能)
XMLHttpRequest Level2 新版本的功能:
- 可以设置HTTP请求的时限。
* 可以使用FormData对象管理表单数据。
* 可以上传文件。
* 可以请求不同域名下的数据(跨域请求)。
* 可以获取服务器端的二进制数据。
* 可以获得数据传输的进度信息。
- 老版本的XMLHttpRequest对象有以下几个缺点:
* 只支持文本数据的传送,无法用来读取和上传二进制文件。
* 传送和接收数据时,没有进度信息,只能提示有没有完成。
* 受到"同域限制"(Same Origin Policy),只能向同一域名的服务器请求数据。
例如
//在php的header中设置"Access-Control-Allow-Origin:*"
方法二JOSNP
- JSONP
JSONP - JavaScript Object Notation Padding
利用 <script> 元素引入外部 JS 不受同源策略限制的特性。只支持GET方式的跨域。
服务器端(后端):
返回一个能够在 JS 中执行的函数调用结构,函数传递的参数即为需要跨域访问到的数据,通常是一个对象。
客户端(前端):
a. 创建 <script> 元素
b. 设置 <script> 元素的 src 属性,src为需要跨域访问的资源URL,通常再传递 "callback" 参数,指明全局回调函数名称
c. 将 <script> 元素添加到 body 中
d. 创建全局函数,用于处理跨域获取到的数据
e. 使用完毕,删除 <script> 元素
实际例子(这里获取了sogou的搜索框友情提示)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<input type="text" id="search">
<button class="btn">点击</button>
<div>
</div>
<script src="include/ajax.js"></script>
<script>
var btn_=sel(".btn",true);
var search_ = sel("#search",true);
var div_ = sel("div",true);
// console.log(btn_,search_,div_);
var html = "";
var sogou={}
sogou.sug = function(data){
data[1].forEach(element => {
html += `<div>${element}</div>`;
});
div_.innerHTML = html;
}
search_.onkeyup = function(){
var _script = document.createElement("script");
_script.src = "http://pic.sogou.com/sugg/ajaj_json.jsp?key="+this.value+"&type=pic";
div_.appendChild(_script);
div_.removeChild(_script);
html ="";
}
</script>
</body>
</html>