跨域请求
2018-05-24 本文已影响84人
SingleDiego
知识点:
- permissions
跨域指的是 JavaScript 通过 XMLHttpRequest
请求数据时,调用 JavaScript
的页面所在的域和被请求页面的域不一致。对于网站来说,浏览器出于安全考虑是不允许跨域。另外,对于域相同,但端口或协议不同时,浏览器也是禁止的。下表给出了进一步的说明:
URL | 说明 | 是否允许请求 |
---|---|---|
http://a.example.com/ , http://a.example.com/a.txt | 同域下 | 允许 |
http://a.example.com/, http://a.example.com/b/a.txt | 同域下不同目录 | 允许 |
http://a.example.com/, http://a.example.com:8080/a.txt | 同域下不同端口 | 不允许 |
http://a.example.com/, https://a.example.com/a.txt | 同域下不同协议 | 不允许 |
http://a.example.com/, http://b.example.com/a.txt | 不同域下 | 不允许 |
http://a.example.com/, http://a.foo.com/a.txt | 不同域下 | 不允许 |
但这个规则如果同样限制 Chrome 扩展应用,就会使其能力大打折扣,所以
Google 允许 Chrome 扩展应用不必受限于跨域限制。但出于安全考虑,需要在 Manifest 的 permissions
属性中声明需要跨域的权限。
比如,如果我们想设计一款获取维基百科数据并显示在其他网页中的扩展,就要在 Manifest 中进行如下声明:
{
...
"permissions": [
"*://*.wikipedia.org/*"
]
}
这样Chrome就会允许你的扩展在任意页面请求维基百科上的内容了。
我们可以利用如下的代码发起异步请求。(详细 ajax 操作参见:原生 Javascript 收发 AJAX)
function httpRequest(url, callback){
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
var resp = JSON.parse(xhr.responseText);
callback(resp);
}
}
xhr.send();
}
鉴于原教程的网址早不提供服务了,下面来写一个新的小 Demo,利用异步请求原来写一个向豆瓣 API 查询图书信息的插件。
编写 manifest.json
:
{
"manifest_version": 2,
"name": "ISBN查询",
"version": "1.0",
"description": "根据ISBN查询书目信息",
"icons": {
"16": "images/icon.png",
"48": "images/icon.png",
"128": "images/icon.png"
},
"browser_action": {
"default_icon": {
"19": "images/icon.png",
"38": "images/icon.png"
},
"default_title": "ISBN查询",
"default_popup": "popup.html"
},
// 设置权限
"permissions": [
"*://api.douban.com/v2/book/isbn/*"
]
}
上面的 Manifest 定义了这个扩展允许对 "*://api.douban.com/v2/book/isbn/*"
发起跨域请求。
popup.html
的结构也完全可以按照时钟的扩展照抄下来,只是个别元素的 id
和脚本的路径根据当前扩展的名称稍加更改,不再赘述。
<html>
<head>
<style>
* {
margin: 0;
padding: 0;
}
body {
width: 250px;
height: 300px;
}
div {
line-height: 50px;
font-size: 20px;
/*text-align: center;*/
}
</style>
</head>
<body>
<div>
<h4>ISBN: <input type="text" name="ISBN", id="ISBN"></h4>
</div>
<div>
<h4 id="title">Title:</h4>
</div>
<br>
<div>
<button id="search">search</button>
</div>
<script src="js/isbn.js"></script>
</body>
</html>
下面编写 my_ip.js
:
// 对某 url 发起异步请求,接收返回的数据传给回调函数执行
function httpRequest(url, callback){
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
var resp = JSON.parse(xhr.responseText);
callback(resp);
}
}
xhr.send();
}
var search = function() {
var isbn = document.getElementById('ISBN').value // 获取输入框的 isbn 值
var url = 'https://api.douban.com/v2/book/isbn/' + isbn // 构建豆瓣 api 的 url
httpRequest(url=url, function(r) {
// 把返回的数据显示在相应位置
var title = r['title']
document.getElementById('title').innerHTML = 'Title: ' + title
})
}
// 选择到按钮
var search_button = document.getElementById("search")
// 把相关函数和点击按钮事件绑定
search_button.addEventListener("click", function(){
search()
})
调试运行: