一个域名下的网站向另外一个域名下的网站请求资源(静态文件)css
好比: 引用别的网站的css link 标签 引入别的网站的js 文件,可是 浏览器有同源策略.有的人会问? 同源策略是啥?html
所谓同源(即指在同一个域)就是两个页面具备相同的协议(protocol),主机(host)和端口号(port)前端
浏览器规定ajax请求只能使用来自于本身网站的数据,不容许使用本身网站之外的数据。
(1). 浏览器容许ajax向其它网站发送请求
(2). 浏览器也容许ajax接收其它网站的响应
(3). 可是浏览器会检查响应数据的来源(origin):
a. 若是数据来源的服务器地址和当前网页所在的地址相同,才能使用数据
b. 若是数据来源的服务器地址和当前网页所在的地址不一样,就不容许使用数据 -----同源策略 (cross orgin resoures shareing)node
下面这些状况都属于跨域,请牢记.jquery
(1). http://www.a.com -> http://www.b.com **域名不一样** (2). http://oa.tedu.com -> http://hr.tedu.com **子域名不一样** (3). http://localhost:3000 -> http://localhost:8080 **端口号不一样** (4). http://12306.cn -> https://12306.cn **协议不一样**
特别提示: 若是你是在一台电脑上进行跨域测试的话 localhost 和127.0.0.1 这就能够实现跨域操做了.ajax
1.若是你的后端是node.js 开发的话 安装expres中间件cors
(1). 项目本地安装cors模块: npm i -save cors
(2)npm
app.use(cors({ origin:['http://localhost:8080', "http://127.0.0.1:5500"], credentials:true }))
2.服务端CORS跨域: 让服务器端在返回数据前,修改响应头中的来源json
地址与前端服务器地址同样。
服务端接口返回数据时,不要用res.send(result) 由于 res.send()里面封装好了浏览器的源头.
应该:后端
res.writeHead(200,{ "Access-Control-Allow-Origin":"http://127.0.0.1:5500" //和前端项目所在服务器的地址保持一致 }); res.write(JSON.stringify(result)); res.end();
不过这个方法的缺点就是你每一个路由都要修改响应头信息.跨域
Jsonp(JSON with Padding) 是 json 的一种"使用模式",可让网页从别的域名(网站)那获取资料,即跨域读取数据。
既然ajax不能够发起跨域请求 可是标签能够 script的属性 src="" 能够实现跨域的请求 可是咱们如何 把这个数据接收到呢?
首先看下服务器端的代码 ,我用的是node.js 中http 模块 和url 模块
const http=require("http"); // 引入bodyparse 中间件 const url=require("url") // 建立服务器 http.createServer((req,res)=>{ var weather="北京 晴 4-24" res.writeHead(200,{ "Content-Type":"text/plain; charset=utf-8" }) // jqery 用callback var fname=url.parse(req.url,true).query.callback var stmt =`${fname}("${weather}")` res.write(stmt) res.end() }).listen(8080) // 解析url 对象
浏览器代码 要用到jquery 将数据类型改成"jsonp" 你会发现已经实现了跨域请求.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script src="jquery-1.11.3.js"></script> </head> <body> <button>今日天气</button> // <!-- <script src="http://localhost:8080?fname=show"></script> --> </body> <script> $("button").click(function(){ // $(` <script src="http://localhost:8080?fname=show">`) // .appendTo("body") $.ajax({ url:"http://localhost:8080", type:"get", dataType:"jsonp", success:function(result){ console.log(result) } }) }) // function show(data){ // alert(data) // } </script> </html>
不少人都很好奇,$ajax()不是不能够跨域? 若是你只看表面那就错了,
接下来和你们探讨下底层原理.
****首先ajax是绝对不能进行跨域,为啥 jquery 实现了呢, 那是jquery dataType:"jsonp"的 里面封装的是这样的一个函数这就是原理.
$(` <script src="http://localhost:8080?fname=show">`) .appendTo("body") //在页面建立一个函数 这个函数的做用 对应的是 function show(data){ $("body>script:last").remove() alert(data) }
这句话啥意思呢就是,点击按钮建立一个script 并加到body 标签的最后,并在全局下建立一个函数 这个函数的做用呢:
**// 服务端 返回的其实一个函数调用语句 show()** 调用以后,并删除<script>标签. 点击按钮 调用函数 ,调用完script 标签 并删除他,防止页面中多余的script 的标签.