最近在做一个我们公司对外接口的开放平台, 就是其他和我们公司有业务交际的公司开发人员可以通过这个 api 开放平台来获取相应接口的信息, 还可以在该平台对接口进行测试. 下面就对我在开发中遇到的坑做一个总结.
1. 跨域
跨域, 这是一个所有前端开发都会遇到的问题. 这次的接口平台本身在一个域名下, 被测试的接口位于 N 个域名下面, 那么跨域范围就必不可少了. 常见的解决跨域方法由前端用 jsonp, 后端配置 cors 这 2 种.
A.JSONP: 兼容 IE8+, 只能 get 请求
这东西面试的时候我不知道被问了多少次了, 可是一直对他模糊, 就是知道有这个方法, 但是如果要我自己去做就不知道该怎么下手, 索性这次给他弄个明白. jsonp-- 网页通过添加一个 <script> 元素, 向服务器请求 JSON 数据, 这种做法不受同源政策限制; 服务器收到请求后, 将数据放在一个指定名字的回调函数里传回来. 来打一个比方. 比如你在本地新建一个文件夹, 里面有一个 index.html, 里面有一个 getJson(), 然后你去请求其他域名下, 比如淘宝 https://www.taobao.com 下面刚好也有一个资源叫做 a.json, 里面有一个 getJson({data}), 那么你就可以对 data 数据进行加工制作了. 下面用代码来演示一遍. html 代码
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Document</title>
- </head>
- <body>
- <script>
- var getJson = function(data){
- alert('我是本地函数, 可以被跨域的 remote.js 文件调用, 远程 js 带来的数据是:' + data.result);
- };
- </script>
- <script src="test1.js"></script>
- </body>
- </html>
javascript 代码
getJson({"result":"我是远程 js 带来的数据"});
上面的 html 里面就有一个 getJson()的函数, 然后在下面的 js 里面也有一个对应的函数, 那么在 html 里面你会发现会弹出 test1.js 里面的数据. 在实际开发中, 如果你是用 jq 这种内裤的话只用把 data : 'json' 改成 data : 'jsonp' 就能实现 jsonp 了, 其他的事情 伟大的 jq 都会帮你完成.
B.CORS: 兼容 IE10+, 允许发任何类型的请求
CORS-- 跨源资源分享 (Cross-Origin Resource Sharing) 的缩写. 它是 W3C 标准, 是跨源 AJAX 请求的根本解决方法. 相比 JSONP 只能发 GET 请求, CORS 允许任何类型的请求. 如果要开启 CORS, 前端什么都不用改, 只要后台改配置, 注意不同的后台配置 CORS 是不一样的 A.PHP 后台 CORS: 1, 允许单个域名访问 指定某域名 (http://client.runoob.com) 跨域访问, 则只需在 http://server.runoob.com/server.php 文件头部添加如下代码 http://client.runoob.xn--com),http-ps4o13nuul4lc9y52a70gbv8ag2d//server.runoob.com/server.php文件头部添加如下代码 : header('Access-Control-Allow-Origin: http://client.runoob.com/'); 2, 允许多个域名访问 指定多个域名 (http://client1.runoob.com,http://client2.runoob.com 等) 跨域访问, 则只需在 http://server.runoob.com/server.php 文件头部添加如下代码 http://client1.runoob.xn--comhttp-0o3f//client2.runoob.com等)跨域访问,则只需在http://server.runoob.com/server.php文件头部添加如下代码 : $origin = isset($_SERVER['HTTP_ORIGIN'])? $_SERVER['HTTP_ORIGIN'] : ''; $allow_origin = array(' http://client1.runoob.com/ ',' http://client2.runoob.com/ '); if(in_array($origin, $allow_origin)){ header('Access-Control-Allow-Origin:'.$origin); } 3, 允许所有域名访问 允许所有域名访问则只需在 http://server.runoob.com/server.php 文件头部添加如下代码: header('Access-Control-Allow-Origin:*');
A.JAVA 后台 CORS: 首先需要下载 cors-filter-1.7.jar,java-property-utils-1.9.jar 这两个 jar 包; 然后配置工程项目中 web.xml 文件, 配置信息如下: json 代码
- <filter>
- <filter-name>CORS</filter-name>
- <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
- <init-param>
- <param-name>cors.allowOrigin</param-name>
- <param-value>*</param-value>
- </init-param>
- <init-param>
- <param-name>cors.supportedMethods</param-name>
- <param-value>GET, POST, HEAD, PUT, DELETE</param-value>
- </init-param>
- <init-param>
- <param-name>cors.supportedHeaders</param-name>
- <param-value>Accept, Origin, X-Requested-With, Content-Type, Last-Modified</param-value>
- </init-param>
- <init-param>
- <param-name>cors.exposedHeaders</param-name>
- <param-value>Set-Cookie</param-value>
- </init-param>
- <init-param>
- <param-name>cors.supportsCredentials</param-name>
- <param-value>true</param-value>
- </init-param>
- </filter>
- <filter-mapping>
- <filter-name>CORS</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
好了, 后台的兄弟配置好了, 我们就能愉快地玩耍了.
2.JS 字符串 False 转 Boolean
这次需要用户自己输入参数, 就会遇到让用户输入 true 这种布尔值, 如果我们不对它做任何处理的话, 那么接口会把它当做字符串来处理, 这显然不是我们想要的结果. 先来看几段代码 javascript 代码
- var hasAuth = 'true';
- if(hasAuth){
- console.log(1);
- }
javascript 代码
- var hasAuth = 'false';
- if(hasAuth){
- console.log(1);
- }
不管是 true 字符串还是 false 字符串 都是 true. 我们需要把字符串布尔值转为为布尔值.
javascript 代码
- console.log( 'false' === 'true');
- console.log( 'true'==='true' );
上面用了 js=== 的性质, 当然也可以用正则获取字符串里面的内容判断, 这种小细节的地方在处理接口时候还有很多, 比如接口参数有中文如果后台没有处理的话 前端要用 encodeURI()转码才行.
- [].forEach.call($$("*"),function(a){
- a.style.outline="1px solid #"+(~~(Math.random()*(1<<24))).toString(16)
- })
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>ajax</title>
- <style type="text/CSS">
- * {
- padding: 0;
- margin: 0;
- }
- .nav-box {
- padding: 20px;
- }
- .nav-box .nav-item {
- float: left;
- margin-left: 20px;
- width: 100px;
- height: 40px;
- line-height: 40px;
- text-align: center;
- position: relative;
- background: #3498db;
- color: #fff;
- font-size: 20px;
- padding-left: 20px;
- text-decoration: none;
- }
- .nav-box .nav-item:before {
- content: '';
- position: absolute;
- left: 0;
- top: 0;
- width: 0;
- height: 0;
- border-top: 20px solid transparent;
- border-left: 20px solid #fff;
- border-bottom: 20px solid transparent;
- }
- .nav-box .nav-item:after {
- content: '';
- position: absolute;
- right: -20px;
- top: 0;
- width: 0;
- height: 0;
- border-top: 20px solid transparent;
- border-left: 20px solid #3498db;
- border-bottom: 20px solid transparent;
- }
- .nav-box .nav-item:first-child:before {
- left: 20px;
- border-left: 20px solid #3498db;
- }
- .nav-box .nav-item:first-child {
- border-top-left-radius:10px;
- border-bottom-left-radius:10px;
- }
- .nav-box .nav-item:last-child:after {
- right: 0;
- border-right: 0 solid #3498db;
- }
- .nav-box .nav-item:last-child {
- border-top-right-radius:10px;
- border-bottom-right-radius:10px;
- }
- </style>
- </head>
- <body>
- <div class="nav-box">
- <a href="javascript:;" class="nav-item">HOME</a>
- <a href="javascript:;" class="nav-item">DREAM</a>
- <a href="javascript:;" class="nav-item">FUTURE</a>
- <a href="javascript:;" class="nav-item">TOP</a>
- </div>
- </body>
- </html>
- (function(w) {
- var lstorage = window.localStorage;
- function lsFile(url) {
- this.url = url;
- this.filename = url.substring(url.lastIndexOf("/")+1,url.lastIndexOf("."));
- this.lname = 'Lsf_'+this.filename+'_'+url.substring(url.lastIndexOf("?")+1);
- this.filetext = null;
- this.init();
- }
- lsFile.prototype = {
- init : function() {
- // 判断是否无痕模式或者浏览器是否支持 ls
- if ( commonMthods.storageTest(window.localStorage) ) {
- this.filetext = lstorage.getItem(this.lname);
- }
- if (this.filetext) {
- alert(1);
- this.eval(this.filetext)
- } else {
- alert(2);
- this.xhr(this.url,this.runstr)
- }
- },
- xhr : function(url, callback) {
- var _this = this,
- version = url.substring(url.lastIndexOf("?")),
- xhr = new XMLHttpRequest();
- xhr.onreadystatechange = function(){
- switch(xhr.readyState) {
- case 4:
- if( xhr.status==200 ) {
- var filetext = xhr.responseText;
- if ( callback ) {
- callback.call(_this,filetext);
- }
- } else {
- alert('加载失败');
- }
- break;
- default:
- break;
- }
- }
- xhr.open('GET',url,false);
- xhr.send();
- },
- runstr : function(filetext) {
- this.eval(filetext);
- lstorage.setItem(this.lname,filetext);
- this.removels();
- },
- removels : function() {
- var arr = [];
- for ( var i = 0; i <lstorage.length; i++ ) {
- var name = lstorage.key(i);
- if( name.indexOf(this.filename)> -1 && name != this.lname ) {
- arr.push(name)
- }
- }
- for (var i in arr) {
- localStorage.removeItem(arr[i]);
- }
- },
- eval : function(filetext) {
- window.eval(filetext);
- }
- }
- w.lsFile = function (url){
- return new lsFile(url)
- };
- })(window)
- lsFile('/m-js/lib/vue.min.js');
来源: http://www.qdfuns.com/article/15098/40bf17fff7991b5d5ef7866c292560d8.html