PHP Ajax 跨域问题最佳解决方案

本文通过设置Access-Control-Allow-Origin来实现跨域。

例如:客户端的域名是client.runoob.com,而请求的域名是server.runoob.com。

如果直接使用ajax访问,会有以下错误:

XMLHttpRequest cannot load http://server.runoob.com/server.php. No 'Access-Control-Allow-Origin' header is present on the requested resource.Origin 'http://client.runoob.com' is therefore not allowed access.

1、允许单个域名访问

指定某域名(http://client.runoob.com)跨域访问,则只需在http://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文件头部添加如下代码:

$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:*'); 

php去除换行(回车换行)的三种方法


<?php   
 //php 不同系统的换行  
//不同系统之间换行的实现是不一样的  
//linux 与unix中用 \n  
//MAC 用 \r  
//window 为了体现与linux不同 则是 \r\n  
//所以在不同平台上 实现方法就不一样  
//php 有三种方法来解决  

//1、使用str_replace 来替换换行  
$str = str_replace(array("\r\n", "\r", "\n"), "", $str);   

//2、使用正则替换  
$str = preg_replace('//s*/', '', $str);  

//3、使用php定义好的变量 (建议使用)  
$str = str_replace(PHP_EOL, '', $str);   
?>  

Markdown image 替换为 html标签

使用Typora可以实现公式的预览,图片自动上传到服务器,但图片是markdown语法,这里实现从Markdown 转化为 Html的 img标签

public static function imageReplace($content)
{

	$pattern = ['/!\[img\]\((.*)\)/U','/<p>\s*<\/p>/U'];

	$replacement = ['<img src="\\1" \/>','']; 

	return preg_replace($pattern, $replacement, $content);

}

实现键盘相关操作

想要实现在写作时作用Enter来提交,作用Ctrl+S保存

    document.onkeydown=keyDownSearch;
   
    function keyDownSearch(e) { 
        // 兼容FF和IE和Opera 
        var theEvent = e || window.event; 
        var code = theEvent.keyCode || theEvent.which || theEvent.charCode; 
        if (code == 13) {  
            $("#todo-btn").trigger('click');
            return false; 
        } 
        return true; 
    }

解决动态ajax/pjax加载mathjax不生效问题

<!DOCTYPE html>
<html>
<head>
<title>MathJax TeX Test Page</title>
<script type="text/x-mathjax-config">
  MathJax.Hub.Config({tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}});
</script>
<script type="text/javascript" async
  src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML">
</script>
</head>
<body>
When $a \ne 0$, there are two solutions to \(ax^2 + bx + c = 0\) and they are
$$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$
</body>
</html>

只要引入mathjax的js地址,配置config,就能自动识别文章中的数学公式写法。显示效果如下:

正常情况下使用,是可以实现显示数学公式的,但是如果你的页面使用了动态加载,即ajax或pjax的情况下,mathjax就不能顺利的渲染出数学公式了。

咳咳,解决动态适配的事情也不是一次两次了,添加事件可以用jquery的on方法委托。在动态调用后执行可以在$.ajax的success方法后执行相关业务逻辑。 pjax则在complete或end后执行相关业务逻辑代码。这里我拿pjax做演示,代码类似下面:

$(document).pjax('a[target!=_top]', '#page', {
    fragment: '#page',
    timeout: 8000,
}).on('pjax:send', function () {
    do something
}).on('pjax:complete', function () {
    $.getScript("//cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.4/MathJax.js?config=TeX-MML-AM_CHTML", function() {
        MathJax.Hub.Config({tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}});
    });
});

想法是在pjax加载complete之后加载mathjax的js依赖,在配置config,因为之前正常使用也是这样的。但是很遗憾,还是没有正常显示。

后来锲而不舍的找到了MathJax.Hub.Typeset()这个方法,结合Queue方法就能实现(不要问我为啥是中文文档,谷歌翻译了解下)

....
.on('pjax:complete', function () {
    $.getScript("//cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.4/MathJax.js?config=TeX-MML-AM_CHTML", function() {
        MathJax.Hub.Config({tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}});
        // entry-content是文章页的内容div的class
        var math = document.getElementsByClassName("entry-content")[0];
        MathJax.Hub.Queue(["Typeset",MathJax.Hub,math]);
    });
});

Katex使用记录

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.15.1/dist/katex.min.css" integrity="sha384-R4558gYOUz8mP9YWpZJjofhk+zx0AS11p36HnD2ZKj/6JR5z27gSSULCNHIRReVs" crossorigin="anonymous">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.15.1/dist/katex.min.js" integrity="sha384-z1fJDqw8ZApjGO3/unPWUPsIymfsJmyrDVWC8Tv/a1HeOtGmkwNd/7xUS0Xcnvsx" crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.15.1/dist/contrib/auto-render.min.js" integrity="sha384-+XBljXPPiv+OzfbB3cVmLHf4hdUFHlWNZN5spNQ7rmHTXpd7WvJum6fIACpNNfIR" crossorigin="anonymous"></script>
<script>
    document.addEventListener("DOMContentLoaded", function() {
        renderMathInElement(document.getElementById('test'), {
          // customised options
          // • auto-render specific keys, e.g.:
          delimiters: [
              {left: '$$', right: '$$', display: true},
              {left: '$', right: '$', display: false},
              {left: '\\(', right: '\\)', display: false},
              {left: '\\[', right: '\\]', display: true}
          ],
          // • rendering keys, e.g.:
          throwOnError : false
        });
    });
</script>

以上代码可以实现公式的渲染,但不能在Ajax加载时渲染,在使用Ajax加载时去除DOMContentLoaded监听即可

清除指定Html标签

/**
 * 删除指定标签
 * @param array  $tags    删除的标签
 * @param string $str     html字符串
 * @param bool   $type    是否保留标签的内容
 * @return mixed
 * @usage
 *  $str = 'Hello</p><p><img src="http://www.baidu.com" /></b><Video>';
 *
 *      // echo strip_tags($str, '<img');
 *      echo $this->stripHtmlTags(array('b','p'),$str,true);
 */
public static function stripHtmlTags($str,$tags=['p','b'], $content=true)
{
    $html = [];
    if($content){
        foreach ($tags as $tag) {
            $html[] = "/(<(?:\/" .$tag. "|" .$tag. ")[^>]*>)/is";
        }
    }else{
        foreach ($tags as $tag) {
            $html[] = '/<' .$tag. '.*?>[\s|\S]*?<\/' .$tag. '>/is';
            $html[] = '/<' .$tag. '.*?>/is';
        }
    }
    $data = preg_replace($html, '', $str);
    return $data;
}

InfiniteScrollPager加载显示记录信息

<div class="text-right">第 <?=(isset($_GET['page'])?$_GET['page']-1:0)*20?>-<?=((isset($_GET['page'])?$_GET['page']:1)*20)>$pages->totalCount?$pages->totalCount:((isset($_GET['page'])?$_GET['page']:1)*20)?> 条, 共 <?=$pages->totalCount?> 条.</div>