ajax处理跨域有几种方式

1、什么是跨域

同源策略是由Netscape提出的著名安全策略,是浏览器最核心、基本的安全功能,它限制了一个源(origin)中加载文本或者脚本与来自其余源(origin)中资源的交互方式
,所谓的同源就是指协议、域名、端口相同。
当浏览器执行一个脚本时会检查是否同源,只有同源的脚本才会执行,若是不一样源即为跨域

 2、出现跨域问题的状况

因为在工做中须要使用AJAX请求其余域名下的请求,可是会出现拒绝访问的状况,这是由于基于安全的考虑,AJAX只能访问本地的资源,而不能跨域访问。javascript

好比说你的网站域名是aaa.com,想要经过AJAX请求bbb.com域名中的内容,浏览器就会认为是不安全的,因此拒绝访问。php

会出现跨域问题的几种状况:html

 

探讨跨域请求资源的几种方式

4、处理跨域的方法2 -- JSONP

 原理
        其本质是利用了标签<img>||<script>具备可跨域的特性, 由服务端返回一个预先定义好的Javascript函数的调用,而且将服务器数据以该函数参数的形式传递过来, 此方法须要先后端配合完成。可是JSONP只支持 “GET” 请求,但不支持 “POST” 请求。前端

服务端JSONP格式数据

jsonp.php 文件代码

<?php
header('Content-type: application/json');
//获取回调函数名
$jsoncallback = htmlspecialchars($_REQUEST ['jsoncallback']);
//json数据
$json_data = '["customername1","customername2"]';
//输出jsonp格式的数据
echo $jsoncallback . "(" . $json_data . ")";
?>java

 

客户端页面完整代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JSONP 实例</title>
</head>
<body>
    <div id="divCustomers"></div>
    <script type="text/javascript">
function callbackFunction(result, methodName)
        {
            var html = '<ul>';
            for(var i = 0; i < result.length; i++)
            {
                html += '<li>' + result[i] + '</li>';
            }
            html += '</ul>';
            document.getElementById('divCustomers').innerHTML = html;
        }
</script>
<script type="text/javascript" src="http://www.runoob.com/try/ajax/jsonp.php?jsoncallback=callbackFunction"></script>
</body>
</html>node

 
jQuery 使用 JSONP

 

缺点:

  一、这种方式没法发送post请求(这里jquery

  二、另外要肯定jsonp的请求是否失败并不容易,大多数框架的实现都是结合超时时间来断定。web

跨域的几种方式

在项目中可能会须要在一个域名下请求另一个域名的资源,下面咱们来探讨下跨域的几种实现方式ajax

一、jsonp

最多见的一种跨域方式,其背后原理就是利用了script标签不受同源策略的限制,在页面中动态插入了script,script标签的src属性就是后端api接口的地址,而且以get的方式将前端回调处理函数名称告诉后端,后端在响应请求时会将回调返还,而且将数据以参数的形式传递回去。json

前端:

//http://127.0.0.1:8888/jsonp.html var script = document.createElement('script'); script.src = 'http://127.0.0.1:2333/jsonpHandler?callback=_callback' document.body.appendChild(script); //插入script标签 //回调处理函数 _callback var _callback = function(obj){ for(key in obj){ console.log('key: ' + key +' value: ' + obj[key]); } }

后端:

//http://127.0.0.1:2333/jsonpHandler app.get('/jsonpHandler', (req,res) => { let callback = req.query.callback; let obj = { type : 'jsonp', name : 'weapon-x' }; res.writeHead(200, {"Content-Type": "text/javascript"}); res.end(callback + '(' + JSON.stringify(obj) + ')'); })

在jsonp.html中打开控制台能够看到返回数据的输出:


jsonp.png

二、CORS

Cross-Origin Resource Sharing(跨域资源共享)是一种容许当前域(origin)的资源(好比html/js/web service)被其余域(origin)的脚本请求访问的机制。
当使用XMLHttpRequest发送请求时,浏览器若是发现违反了同源策略就会自动加上一个请求头:origin,后端在接受到请求后肯定响应后会在Response Headers中加入一个属性:Access-Control-Allow-Origin,值就是发起请求的源地址(http://127.0.0.1:8888),浏览器获得响应会进行判断Access-Control-Allow-Origin的值是否和当前的地址相同,只有匹配成功后才进行响应处理。

现代浏览器中和移动端都支持CORS(除了opera mini),IE下须要8+

前端:

//http://127.0.0.1:8888/cors.html var xhr = new XMLHttpRequest(); xhr.onload = function(data){ var _data = JSON.parse(data.target.responseText) for(key in _data){ console.log('key: ' + key +' value: ' + _data[key]); } }; xhr.open('POST','http://127.0.0.1:2333/cors',true); xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); xhr.send();

后端:

//http://127.0.0.1:2333/cors app.post('/cors',(req,res) => { if(req.headers.origin){ res.writeHead(200,{ "Content-Type": "text/html; charset=UTF-8", "Access-Control-Allow-Origin":'http://127.0.0.1:8888' }); let people = { type : 'cors', name : 'weapon-x' } res.end(JSON.stringify(people)); } })

能够在开发者工具里面看到请求的详细信息,而且在控制台也能够看到返回的数据输出:


response header.png

cors console.png

三、服务器跨域

在先后端分离的项目中能够借助服务器实现跨域,具体作法是:前端向本地服务器发送请求,本地服务器代替前端再向api服务器接口发送请求进行服务器间通讯,本地服务器其实就是个中转站的角色,再将响应的数据返回给前端,下面用node.js作一个示例

前端:

//http://127.0.0.1:8888/server var xhr = new XMLHttpRequest(); xhr.onload = function(data){ var _data = JSON.parse(data.target.responseText) for(key in _data){ console.log('key: ' + key +' value: ' + _data[key]); } }; xhr.open('POST','http://127.0.0.1:8888/feXhr',true); //向本地服务器发送请求 xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); xhr.send("url=http://127.0.0.1:2333/beXhr"); //以参数形式告知须要请求的后端接口

后端:

//http://127.0.0.1:8888/feXhr app.post('/feXhr',(req,res) => { let url = req.body.url; superagent.get(url) //使用superagent想api接口发送请求 .end(function (err,docs) { if(err){ console.log(err); return } res.end(docs.res.text); //返回到前端 }) }) //http://127.0.0.1:2333/beXhr app.get('/beXhr',(req,res) => { let obj = { type : 'superagent', name : 'weapon-x' }; res.writeHead(200, {"Content-Type": "text/javascript"}); res.end(JSON.stringify(obj)); //响应 })

回到 http://127.0.0.1:8888/server 页面打开控制台能够看到数据输出:

 

 

5、处理跨域的方法3 -- XHR2

“XHR2” 全称 “XMLHttpRequest Level2” 是HTML5提供的方法,对跨域访问提供了很好的支持,而且还有一些新的功能。

* IE10如下的版本都不支持

* 只须要在服务器端头部加上下面两句代码:

header( "Access-Control-Allow-Origin:*" );

header( "Access-Control-Allow-Methods:POST,GET" );

相关文章
相关标签/搜索