小左闲谈

AJAX请求跨域问题的解决方案

In 笔记  @2018-04-24

这个问题其实刚入行的时候就碰到了,后来就在接口返回数据返回的函数里加了一行代码:

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

一直想总结一下这个让很多新手困扰的跨域问题,现在来说一说。
首先,跨域产生的原因大家可以自行百度。
本地测试从http://localhosthttp://192.168.50.88域请求数据。

测试代码:

前台代码:

$.get('http://192.168.50.88/tp_test/Home/Test/test_jsonp', function(data) {
    console.log(data);
});

后台代码:

public function test_jsonp(){
    $data = json_encode(array(
        'uid'=>5465,
        'nick'=>'刘德华1265'
    ));
    echo $data;
}

在不做任何处理的情况下浏览器会提示跨域权限问题的,无法获取到数据。

Failed to load http://192.168.50.88/tp_test/Home/Test/test_jsonp: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access

解决方案

方案一:JSONP

这个方案虽然很古老,但依然有效,对于小型的GET请求任务还是可以胜任的,原理很取巧,理解它还是很有必要的;
他的原理就是,通过向页面添加<script></script>标签,加载接口,后台接口按照约定好的将数据放到接口中获取到的callback函数中,前台通过这个函数运行来获取到数据。
代码修改如下:
前台代码:

// callback函数叫jsonp_callback
$(document).ready(function() {
    CreateScript('http://192.168.50.88/tp_test/Home/Test/test_jsonp?callback=jsonp_callback');
});
// callback函数jsonp_callback
function jsonp_callback(data){
    console.log(data);
}
// 添加script标签
function CreateScript(src){  
    $("<script><//script>").attr("src", src).appendTo("body");
} 

后台代码:

public function test_jsonp(){
    $callback = $_GET['callback'];
    $data = json_encode(array(
        'uid'=>5465,
        'nick'=>'刘德华1265'
    ));
    echo "{$callback}({$data})";
}

可以看到,已经可以正确的将数据获取到了,这也就是JSONP的实现过程,由于这样的实现原理,导致了JSONP的两个问题:
1. 需要后台配合返回约定格式的数据。
2. JSONP只能发送GET请求。
而在使用Jquery封装好的jsonp请求时,就会更加方便一些了,同样的后端代码,前端代码就可以做简化了:

$.ajax({
    url: 'http://192.168.50.88/tp_test/index.php/Home/Test/test_jsonp',
    dataType: 'jsonp',
    jsonp:'callback',
})
.done(function(data) {
    console.log(data);
})

Jquery的封装帮我们完成了所有前台需要完成的工作,只需要后台将数据放到callback中返回就可以了。
由于JSONP只能发送GET请求,其他的场景就需要第二种方案;

方案二:HTTP访问控制(CORS)

CORS是一个W3C标准,全称是"跨域资源共享"Cross-origin resource sharing。它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
CORSJSONP的使用目的相同,但是比JSONP更强大。JSONP只支持GET请求,CORS支持所有类型的HTTP请求。JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。
CORS的用法很简单:我们只需要的被请求的接口的回复头中添加:

// 星号表示所有的域都可以请求这里的数据
Access-Control-Allow-Origin: *
//或者指定域,例如上面的测试中我们需要加入即可正常得到数据了
Access-Control-Allow-Origin: http://localhost

关于CORS更多的设置和用法请自行搜索。

标签: , , , , ,   评论: 抢沙发 

ThinkPHP 3.2.3 实现前台多语言切换

In 笔记  @2018-04-23

由于公司项目需要,多个客户有开发双语站点的需求,又由于下载来的CMS二次开发起来很费时间,项目差异导致每次使用得再来一次,加上前人留下来的东西无法整合进去,于是前端时间基于ThinkPHP3.2.3写了一套CMS系统,就将平时工作用户需求很高的一些功能整合进去了,其中一个功能就是这个中英文的切换。

思路

简单的思路,用户第一次进来默认中文,当用户点击了前台的中英文切换,将用户的选择的语言存储到cookie,加载页面的时候读取cookie中的语言设置并将其作为变量传给前台供模版渲染使用。

步骤

  1. /Application/Common/Conf的配置文件config.php文件中开启多语言功能;
    // 多语言包开启
    'LANG_SWITCH_ON'    => true, // 开启多语言
    'LANG_AUTO_DETECT'  => true, // 自动侦测语言
    'DEFAULT_LANG'      => 'zh-cn', // 默认语言
    'LANG_LIST'         => 'zh-cn, en-us', // 允许的语言列表
    'VAR_LANGUAGE'      => 'lang', // 默认语言切换变量
  1. /Application/Common/Conf下一个文件命名为tags.php,代码如下:
<?php 
/**
 * 多语言切换使用
 */
return array(
    'app_begin' => array('Behavior\CheckLangBehavior'),
)
?>
  1. /Application/Home/新建Lang文件夹,新建语言文件zh-cn.phpen-us.php,这里的翻译是提供给模版或者后台的L方法使用,这里可以放一些前端模版中除正文标题等数据库录入的中英文以外的翻译短语。
<?php
// zh-cn.php
return array(
    '示例'=>'我是中文',
    '测试'=>'我是测试',
    '首页'=>'首页',
    '404错误' => '404错误',
    '上一篇'=>'上一篇',
    '下一篇'=>'下一篇',
    '没有更多文章了'=>'没有更多文章了',
    '您现在的位置'=>'您现在的位置',
);
?>
<?php 
// en-us.php
return array(
    '示例'=>'English Page',
    '测试'=>'This is a test',
    '首页'=>'Home Page',
    '404错误'=>'404 NOT FOUND',
    '上一篇'=>'Prev',
    '下一篇'=>'next',
    '没有更多文章了'=>'No More Post',
    '您现在的位置'=>'current page',
);
?>
  1. 在能提供前台访问的控制器中写一个切换语言的接口,我这里放在/Application/Home/Controller/IndexController中取名lang()
    /**
     * 语言切换
     * @method GET 
     * @param string $lang 'cn' || 'en'
     * @Author       hsu1943
     * @DateTime     2018-04-09T15:44:27+0800
     * @return   
     */
    public function lang(){
        switch(I('get.lang')){
            case 'cn':
                cookie('think_language',null);
                cookie('think_language','zh-cn'); 
                break;
            case 'en':
                cookie('think_language',null);
                cookie('think_language','en-us');
                break;
        }
    }
  1. 在前台模版文件中添加切换按钮HTML代码;
<!-- 多语言切换 -->
<div class="lang">
    <a class="langBtn" lang="cn" href="javascript:void(0);">中文</a>
    <a class="langBtn" lang="en" href="javascript:void(0);">ENGLISH</a>
</div>
  1. HTML代码加上添加异步请求的JS代码,完成多语言切换功能;
var url = 'http://www.test.com/index.php/Home/Index/lang';
//中英文切换
$('.langBtn').on('click', function(){
    var data={'lang':$(this).attr('lang')}
    $.get(url, data, function(e){
        location.reload();
    })
})

至此,基于ThinkPHP3.2.3实现了多语言切换的功能了,当然,文章主要内容标题这些需要后台来添加的内容是需要存多语言版本到数据库,我在使用的时候是输出到模版的时候取出全部语言的内容,然后在输出的通过后台告诉我的当前用户选择的是什么语言,我就输出什么语言的内容,当然你也可以在查询的时候就先判断语言,然后查询该语言对应的内容输出即可;

标签: , , ,   评论: 抢沙发 

Centos常用命令记录之:iptables

In 笔记  @2018-02-01

Centos防火墙的设置,在Centos 7之前的版本中大量都是在使用iptables,项目服务器的运维上急需相关知识;

  • 首先,记住iptables的配置文件的位置/etc/sysconfig/iptables,修改前最好备份一下;

iptables相关命令:

  • 查看现有的iptables规则:
service iptables status
Table: filter
Chain INPUT (policy DROP)
num  target     prot opt source           destination         
1    ACCEPT     tcp  --  0.0.0.0/0        0.0.0.0/0       state NEW tcp dpt:8090 
2    ACCEPT     tcp  --  0.0.0.0/0        0.0.0.0/0       state NEW tcp dpt:3306 
3    ACCEPT     tcp  --  0.0.0.0/0        0.0.0.0/0       state NEW tcp dpt:80 
4    ACCEPT     tcp  --  0.0.0.0/0        0.0.0.0/0       state NEW tcp dpt:22 
5    ACCEPT     tcp  --  0.0.0.0/0        0.0.0.0/0       state NEW tcp dpt:21 
6    ACCEPT     icmp --  0.0.0.0/0        0.0.0.0/0       icmp type 255 
7    ACCEPT     all  --  127.0.0.1        127.0.0.1           
8    ACCEPT     all  --  0.0.0.0/0        0.0.0.0/0       state RELATED,ESTABLISHED 

Chain FORWARD (policy ACCEPT)
num  target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination
  • 添加/插入规则
#使用A(ADD)命令在规则的结尾添加一条
iptables -A
#使用I(INSERT)命令在指定位置插入一条
iptables -I
  • 删除现有的规则,删除上面INPUT表中的序号为1的规则:
iptables -D INPUT 1
  • 保存规则
service iptables save
  • 重载规则
service iptables restart

这些就是基本的iptables操作了。

标签: , , , ,   评论: 2枚