js 跨域的几种常见解决方案
来源:互联网 发布:企业数据备份方案 编辑:程序博客网 时间:2024/05/21 14:06
1. JSONP(JSON with Padding)
JSONP 技术的原理介绍
jsonp 的实现是基于html标签中src属性的数据源特性, 部分 html 标签比如 img script 可以通过 src 进行跨域访问,而浏览器不可能对这一行为进行阻止,虽然,浏览不支持js语言直接进行跨域http请求,但是我们可以间接的通过 src 属性从服务器返回一个 js 回调函数 从而实现跨域请求的目的
1. 简单的例子
浏览器端
<script type="text/javascript"> // 1 定义一个带参数回调函数 function fn(data){ alert(data); } </script> //2 通过 srcipt标签的 src 属性从服务器返回一个 fn(data)回调 <script src='http://www.test.com/jsonp/callJs.php'></script>
服务器 php 端
<?php // 3 返回一个在请求页里定义好的js函数,并把参数返回 echo "fn('你好')";
2. 简单封装
1封装JS函数
function jsonp(params) {//获取 head 标签var head = document.querySelector('head');//创建 script 标签var script = document.createElement('script');//创建回调函数var call = "fn" + new Date().getTime();window[call] = function(arg) {console.log(arg);params.success(arg);// alert(3);}//请求 参数中 url 地址 并将 回调函数做为参数添加到 url script.src = params.url + '?callback=' + call;head.appendChild(script);}
# 2 在 html 中引用
<script src="./jsonp.js" /></script><script type="text/javascript"> // 调用封装好的方法 并传递 url 和 请求成功后的回调函数 jsonp({ url: "http://www.longtaoge.com/jsonp/php/js.php", success: function(repose) { console.log(repose); //处理数据 fillData(repose); } });</script>
3 php返回数据
<?php //获取Get 请求中 jsop 的回调 $cal=!empty($_GET['callback'])?$_GET['callback']:''; //从文件中读取数据并返回 $va=file_get_contents("../data/data.json"); //返回数据 echo $cal.'('.$va.')'; ?>
3. 模似封装 ajax
# 1 封装 ajax 函数
//声明一个对象function $() {}//模仿ajax 函数$.ajax = function(params) {//获取参数 请示地址 var url = params.url || location.pathname;var type = params.type || 'get'; //请求方式var data = params.data || {}; //获取请求参数var dataType = params.dataType; //jsonp//如果需要跨域 if (dataType == 'jsonp') { var head = document.querySelector('head'); var script = document.createElement('script'); //模仿jQuery 的回调函数 var call = 'jQuery' + new Date().getTime(); url = url + '?callback=' + call; if (type == "get") { // 通过Get 请求添加附加参数 url += "&"+dataFomart(data); //清空参数 data = null; } //通过 script 标签的 src 属性 请求 script.src = url; head.appendChild(script); window[call] = function(arg) { params.success(arg); } return;}//格式化请求参数function dataFomart(data) { var strs = ''; for (var vl in data) { strs += vl + '=' + data[vl] + '&'; } console.log(strs); return strs.slice(0, -1);}if (type == "get") { url += '?' + dataFomart(data); data = null;}// ajax var xhr = new XMLHttpRequest();xhr.open(type, url);if (type == "post") { xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');}xhr.send(dataFomart(data));xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { //解析为json var str = JSON.parse(xhr.responseText); params.success(str); }}
};
2 在html 中引用自定义ajax
<script src='ajax.js'></script><script type="text/javascript">var btn = document.querySelector('.btn');btn.onclick = function() { $.ajax({ url: 'http://www.longtaoge.com/jsonp/demo.php', type: 'get', data: { name: '小明', age: 12 }, dataType: 'jsonp', success: function(data) { console.log(data); // 处理返回数据 fillData(data); } });}
3 服务器端返回数据
<?php header("Content-type:text/json;charset=utf-8"); //获取回调方法 $cal=!empty($_GET['callback'])?$_GET['callback']:''; //获取相关参数 $name=!empty($_REQUEST['name'])?$_REQUEST['name']:""; $age=!empty($_REQUEST['age'])?$_REQUEST['age']:""; //从文件中取出模似数据 $va=file_get_contents("./data/data.json"); $vaObj=json_decode($va); //TODO 处理数据 if (empty($cal)) { // 参数 echo json_encode($vaObj); }else{ // 跨域回调 echo $cal.'('.json_encode($vaObj).')'; }
2. CORS(Cross-origin resource sharing)
CORS是一个W3C标准,全称是”跨域资源共享” , cors 需要浏览器和服务器的支持,现在主流的浏览器均支持这一标准.
服务器端 需要对响应头进行相应的配置实现这一功能
举例说明:在网站 test.com 有一个向 www.longtaoge.com 发起的js简单请求http://www.test.com/cors/cors.html <script type="text/javascript">var xhr = new XMLHttpRequest;xhr.open('get', 'http://www.longtaoge.com/cors/cors.php');xhr.send();xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { console.log(xhr.responseText); document.write(xhr.responseText); }}</script>
直接请求浏览器将提示以下错误信息
cors.html:1 XMLHttpRequest cannot load http://www.homework.com/cors/cors.php. No 'Access-Control-Allow-Origin' header is present on the requested resource.Origin 'http://www.test.com' is therefore not allowed access.
http://www.longtaoge.com/cors/cors.php
可以在响应头中设置 Access-Control-Allow-Origin 实现跨域请求
<?php header('Access-Control-Allow-Origin:http://www.test.com'); //允许 www.test.com 的跨域请求 //header('Access-Control-Allow-Origin:*'); //允许所有网站的跨域请求 echo "来自 www.homework.com 的数据 ";?>
再次访问
3. 配置apache反向代理实现浏览跨域
1 apache 配置
- 打开配置文件httpd.conf
开启 proxy_http_module 和 proxy_module 模块,将#号删除
#LoadModule proxy_module modules/mod_proxy.so #LoadModule proxy_http_module modules/mod_proxy_http.so
代理详细配置
可以单独为某一个虚拟主机配置反向代理,这样不同的虚拟主机就可以被代理到不同的服务器了
开启辅配置,将#号删除
#Include conf/extra/httpd-vhosts.conf
配置虚拟主机
<VirtualHost *:80> ServerAdmin 61852263@qq.com DocumentRoot "E:/www/test" ServerName test.com #本服务器域名 ServerAlias www.test.com ErrorLog "logs/dummy-host.studyit.com-error.log" CustomLog "logs/dummy-host.studyit.com-access.log" common ProxyRequests Off # 访问/api 相当于访问 http://www.longtaoge.com:80 ProxyPass /api http://www.longtaoge.com:80 # 这样所有的请求就经过 /api 被代理到 http://www.longtaoge.com:80了 # /api 也不是固定的,可以自行调整
2 html 访问接口
<script type="text/javascript"> // 通过服务器代理 相当于访问 http://www.longtaoge.com/jsonp/demo.php var url = '/api/jsonp/demo.php'; var xhr = new XMLHttpRequest(); xhr.open('get', url); xhr.send(); xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { //解析为json var str = JSON.parse(xhr.responseText); console.log(str); } } </script>
3 服务器返回数据
<?php header("Content-type:text/json;charset=utf-8");//模似数据$va=file_get_contents("./data/data.json");$vaObj=json_decode($va);//返回输出echo json_encode($vaObj);
阅读全文
1 0
- js 跨域的几种常见解决方案
- js跨域的几种解决方案
- 关于JS的跨域通信的几种解决方案
- 常见js跨域解决方案
- js跨域问题 常见的集中解决方案
- 几种常见的js表单验证
- JS几种常见的用户名检测
- 几种常见的js数据类型转变
- js数组几种常见的操作方法
- js几种常见排序的实现
- ajax跨域和JS的跨域通信(Cross The Site)的几种解决方案
- iframe跨域、ajax跨域和JS跨域通信的几种解决方案
- java常见的几种内存溢出和解决方案
- java常见的几种内存溢出和解决方案
- 常见的几种浏览器兼容性问题和解决方案
- 常见的几种浏览器问题以及解决方案
- java常见的几种内存溢出和解决方案
- php网站开发常见的几种攻击以及解决方案
- Java面试总结
- 菜鸟学Java学习笔记小结 2017.08.17
- hdu3367(并查集+kruscal)
- C#二维数组
- vc根据域名获取IP地址 gethostbyname()函数
- js 跨域的几种常见解决方案
- servlet知识点
- 串的模式匹配
- Redis.conf配置文件示例
- 用java打印出几种图形及简单的了解下循环
- Hadoop学习之Hive简介
- c++多态的实现原理
- SpringBoot~Spring Security入门
- js 的基础知识