如何解决什么是ajax跨域问题题

js中几种实用的跨域方法原理详解 - 无双 - 博客园
这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据。只要协议、域名、端口有任何一个不同,都被当作是不同的域。
下表给出了相对http://store.company.com/dir/page.html同源检测的结果:
要解决跨域的问题,我们可以使用以下几种方法:
一、通过jsonp跨域
在js中,我们直接用XMLHttpRequest请求不同域上的数据时,是不可以的。但是,在页面上引入不同域上的js脚本文件却是可以的,jsonp正是利用这个特性来实现的。
比如,有个a.html页面,它里面的代码需要利用ajax获取一个不同域上的json数据,假设这个json数据地址是,那么a.html中的代码就可以这样:
我们看到获取数据的地址后面还有一个callback参数,按惯例是用这个参数名,但是你用其他的也一样。当然如果获取数据的jsonp地址页面不是你自己能控制的,就得按照提供数据的那一方的规定格式来操作了。
因为是当做一个js文件来引入的,所以返回的必须是一个能执行的js文件,所以这个页面的php代码可能是这样的:
最终那个页面输出的结果是:
所以通过得到的js文件,就是我们之前定义的dosomething函数,并且它的参数就是我们需要的json数据,这样我们就跨域获得了我们需要的数据。
这样jsonp的原理就很清楚了,通过script标签引入一个js文件,这个js文件载入成功后会执行我们在url参数中指定的函数,并且会把我们需要的json数据作为参数传入。所以jsonp是需要服务器端的页面进行相应的配合的。
知道jsonp跨域的原理后我们就可以用js动态生成script标签来进行跨域操作了,而不用特意的手动的书写那些script标签。如果你的页面使用jquery,那么通过它封装的方法就能很方便的来进行jsonp操作了。
原理是一样的,只不过我们不需要手动的插入script标签以及定义回掉函数。jquery会自动生成一个全局函数来替换callback=?中的问号,之后获取到数据后又会自动销毁,实际上就是起一个临时代理函数的作用。$.getJSON方法会自动判断是否跨域,不跨域的话,就调用普通的ajax方法;跨域的话,则会以异步加载js文件的形式来调用jsonp的回调函数。
2、通过修改document.domain来跨子域
浏览器都有一个同源策略,其限制之一就是第一种方法中我们说的不能通过ajax的方法去请求不同源中的文档。 它的第二个限制是浏览器中不同域的框架之间是不能进行js的交互操作的。有一点需要说明,不同的框架之间(父子或同辈),是能够获取到彼此的window对象的,但蛋疼的是你却不能使用获取到的window对象的属性和方法(html5中的postMessage方法是一个例外,还有些浏览器比如ie6也可以使用top、parent等少数几个属性),总之,你可以当做是只能获取到一个几乎无用的window对象。比如,有一个页面,它的地址是& , 在这个页面里面有一个iframe,它的src是, 很显然,这个页面与它里面的iframe框架是不同域的,所以我们是无法通过在页面中书写js代码来获取iframe中的东西的:
这个时候,document.domain就可以派上用场了,我们只要把 和 这两个页面的document.domain都设成相同的域名就可以了。但要注意的是,document.domain的设置是有限制的,我们只能把document.domain设置成自身或更高一级的父域,且主域必须相同。例如:a.b.example.com 中某个文档的document.domain 可以设成a.b.example.com、b.example.com 、example.com中的任意一个,但是不可以设成 c.a.b.example.com,因为这是当前域的子域,也不可以设成baidu.com,因为主域已经不相同了。
中设置document.domain:
中也设置document.domain,而且这也是必须的,虽然这个文档的domain就是example.com,但是还是必须显示的设置document.domain的值:
这样我们就可以通过js访问到iframe中的各种属性和对象了。
不过如果你想在 页面中通过ajax直接请求 页面,即使你设置了相同的document.domain也还是不行的,所以修改document.domain的方法只适用于不同子域的框架间的交互。如果你想通过ajax的方法去与不同子域的页面交互,除了使用jsonp的方法外,还可以用一个隐藏的iframe来做一个代理。原理就是让这个iframe载入一个与你想要通过ajax获取数据的目标页面处在相同的域的页面,所以这个iframe中的页面是可以正常使用ajax去获取你要的数据的,然后就是通过我们刚刚讲得修改document.domain的方法,让我们能通过js完全控制这个iframe,这样我们就可以让iframe去发送ajax请求,然后收到的数据我们也可以获得了。
3、使用window.name来进行跨域
window对象有个name属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每个页面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的,并不会因新页面的载入而进行重置。
比如:有一个页面a.html,它里面有这样的代码:
再看看b.html页面的代码:
a.html页面载入后3秒,跳转到了b.html页面,结果为:
我们看到在b.html页面上成功获取到了它的上一个页面a.html给window.name设置的值。如果在之后所有载入的页面都没对window.name进行修改的话,那么所有这些页面获取到的window.name的值都是a.html页面设置的那个值。当然,如果有需要,其中的任何一个页面都可以对window.name的值进行修改。注意,window.name的值只能是字符串的形式,这个字符串的大小最大能允许2M左右甚至更大的一个容量,具体取决于不同的浏览器,但一般是够用了。
上面的例子中,我们用到的页面a.html和b.html是处于同一个域的,但是即使a.html与b.html处于不同的域中,上述结论同样是适用的,这也正是利用window.name进行跨域的原理。
下面就来看一看具体是怎么样通过window.name来跨域获取数据的。还是举例说明。
比如有一个页面,需要通过a.html页面里的js来获取另一个位于不同域上的页面里的数据。
data.html页面里的代码很简单,就是给当前的window.name设置一个a.html页面想要得到的数据值。data.html里的代码:
那么在a.html页面中,我们怎么把data.html页面载入进来呢?显然我们不能直接在a.html页面中通过改变window.location来载入data.html页面,因为我们想要即使a.html页面不跳转也能得到data.html里的数据。答案就是在a.html页面中使用一个隐藏的iframe来充当一个中间人角色,由iframe去获取data.html的数据,然后a.html再去得到iframe获取到的数据。
充当中间人的iframe想要获取到data.html的通过window.name设置的数据,只需要把这个iframe的src设为就行了。然后a.html想要得到iframe所获取到的数据,也就是想要得到iframe的window.name的值,还必须把这个iframe的src设成跟a.html页面同一个域才行,不然根据前面讲的同源策略,a.html是不能访问到iframe里的window.name属性的。这就是整个跨域过程。
看下a.html页面的代码:
上面的代码只是最简单的原理演示代码,你可以对使用js封装上面的过程,比如动态的创建iframe,动态的注册各种事件等等,当然为了安全,获取完数据后,还可以销毁作为代理的iframe。网上也有很多类似的现成代码,有兴趣的可以去找一下。
通过window.name来进行跨域,就是这样子的。
4、使用HTML5中新引进的window.postMessage方法来跨域传送数据
window.postMessage(message,targetOrigin)& 方法是html5新引进的特性,可以使用它来向其它的window对象发送消息,无论这个window对象是属于同源或不同源,目前IE8+、FireFox、Chrome、Opera等浏览器都已经支持window.postMessage方法。
调用postMessage方法的window对象是指要接收消息的那一个window对象,该方法的第一个参数message为要发送的消息,类型只能为字符串;第二个参数targetOrigin用来限定接收消息的那个window对象所在的域,如果不想限定域,可以使用通配符 *& 。
需要接收消息的window对象,可是通过监听自身的message事件来获取传过来的消息,消息内容储存在该事件对象的data属性中。
上面所说的向其他window对象发送消息,其实就是指一个页面有几个框架的那种情况,因为每一个框架都有一个window对象。在讨论第二种方法的时候,我们说过,不同域的框架间是可以获取到对方的window对象的,而且也可以使用window.postMessage这个方法。下面看一个简单的示例,有两个页面
我们运行a页面后得到的结果:
我们看到b页面成功的收到了消息。
使用postMessage来跨域传送数据还是比较直观和方便的,但是缺点是IE6、IE7不支持,所以用不用还得根据实际需要来决定。
除了以上几种方法外,还有flash、在服务器上设置代理页面等跨域方式,这里就不做介绍了。
以上四种方法,可以根据项目的实际情况来进行选择应用,个人认为window.name的方法既不复杂,也能兼容到几乎所有浏览器,这真是极好的一种跨域方法。AJAX 跨域解决方案 - CORSa year ago三种解决方案:方案一://弊端:存在浏览器兼容的问题。需要被请求方的服务端设置: Access-Control-Allow-Origin切记:Access-Control-Allow-Origin 不可设置为 * ,设置为可访问的域名。//设置可供访问的白名单
$white_list = ['http://cdn.abc.com','http://abc.com'];
$_SERVER['HTTP_ORIGIN'] //表示请求方的域名
$http_origin = '';
if (!empty($_SERVER['HTTP_ORIGIN']) && in_array($_SERVER['HTTP_ORIGIN'],$white_list)) {
$http_origin = $_SERVER['HTTP_ORIGIN'];
//设置 header 信息
header("Access-Control-Allow-Origin: {$http_origin}");
header("Access-Control-Allow-Methods", "POST,GET");
header('Access-Control-Allow-Credentials:true');
//允许访问Cookie
header('Access-Control-Allow-Headers : X-Requested-With'); //设置Headers
//执行代码逻辑...
另:如果请求的是html,在文件里加上meta标签。&meta http-equiv="Access-Control-Allow-Origin" content="*"&
方案二://弊端:不支持 POST 请求。使用 JSONP 进行解决跨域问题,网上文章蛮多的。方案三:与方案一类似。修改Nginx Apache 配置://Nginx
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers X-Requested-W
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
&Directory /&
Header set Access-Control-Allow-Origin *
&/Directory&
大家可以根据自己的情况进行选择方案。Thanks ~赞赏还没有人赞赏,快来当第一个赞赏的人吧!1收藏分享举报文章被以下专栏收录技术的深度和广度只能靠自己努力去发掘。{&debug&:false,&apiRoot&:&&,&paySDK&:&https:\u002F\u002Fpay.zhihu.com\u002Fapi\u002Fjs&,&wechatConfigAPI&:&\u002Fapi\u002Fwechat\u002Fjssdkconfig&,&name&:&production&,&instance&:&column&,&tokens&:{&X-XSRF-TOKEN&:null,&X-UDID&:null,&Authorization&:&oauth c3cef7c66aa9e6a1e3160e20&}}{&database&:{&Post&:{&&:{&isPending&:false,&contributes&:[{&sourceColumn&:{&lastUpdated&:,&description&:&&,&permission&:&COLUMN_PUBLIC&,&memberId&:3885784,&contributePermission&:&COLUMN_PUBLIC&,&translatedCommentPermission&:&all&,&canManage&:true,&intro&:&技术的深度和广度只能靠自己努力去发掘。&,&urlToken&:&IT-Group&,&id&:20316,&imagePath&:&v2-f75b94eb56ceecfa96117b5.jpg&,&slug&:&IT-Group&,&applyReason&:&0&,&name&:&IT小圈儿&,&title&:&IT小圈儿&,&url&:&https:\u002F\u002Fzhuanlan.zhihu.com\u002FIT-Group&,&commentPermission&:&COLUMN_ALL_CAN_COMMENT&,&canPost&:true,&created&:,&state&:&COLUMN_NORMAL&,&followers&:116,&avatar&:{&id&:&v2-f75b94eb56ceecfa96117b5&,&template&:&https:\u002F\u002Fpic1.zhimg.com\u002F{id}_{size}.jpg&},&activateAuthorRequested&:false,&following&:false,&imageUrl&:&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-f75b94eb56ceecfa96117b5_l.jpg&,&articlesCount&:28},&state&:&accepted&,&targetPost&:{&titleImage&:&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-bb2b70dfe92d34a25b4e_r.jpg&,&lastUpdated&:,&imagePath&:&v2-bb2b70dfe92d34a25b4e.jpg&,&permission&:&ARTICLE_PUBLIC&,&topics&:[],&summary&:&什么是AJAX?AJAX 是无需刷新页面就能够从服务器去的数据的一种方法,负责Ajax运作的核心对象是XMLHttpRequest(XHR)对象。同源策略是对XHR的一个主要约束,它为通信设置了“相同的域、相同的端口、相同的协议”这一限制。 试图访问上述限制之外的资源都会引…&,&copyPermission&:&ARTICLE_COPYABLE&,&translatedCommentPermission&:&all&,&likes&:0,&origAuthorId&:0,&publishedTime&:&T11:58:10+08:00&,&sourceUrl&:&&,&urlToken&:,&id&:1246040,&withContent&:false,&slug&:,&bigTitleImage&:false,&title&:&AJAX 跨域解决方案 - CORS&,&url&:&\u002Fp\u002F&,&commentPermission&:&ARTICLE_ALL_CAN_COMMENT&,&snapshotUrl&:&&,&created&:,&comments&:0,&columnId&:20316,&content&:&&,&parentId&:0,&state&:&ARTICLE_PUBLISHED&,&imageUrl&:&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-bb2b70dfe92d34a25b4e_r.jpg&,&author&:{&bio&:&优秀是一种品质,卓越是一种境界。&,&isFollowing&:false,&hash&:&546c8be20acff8bd1f88&,&uid&:36,&isOrg&:false,&slug&:&nick-dreamer&,&isFollowed&:false,&description&:&技术个人总结,将同步记录到公众号中。\n个人公众号:IT小圈儿\n账号:ToFeelings&,&name&:&Dreamer&,&profileUrl&:&https:\u002F\u002Fwww.zhihu.com\u002Fpeople\u002Fnick-dreamer&,&avatar&:{&id&:&f27f2e495f4&,&template&:&https:\u002F\u002Fpic2.zhimg.com\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},&memberId&:3885784,&excerptTitle&:&&,&voteType&:&ARTICLE_VOTE_CLEAR&},&id&:439565}],&title&:&AJAX 跨域解决方案 - CORS&,&author&:&nick-dreamer&,&content&:&\u003Cblockquote\u003E\u003Cp\u003E什么是AJAX?\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Cp\u003EAJAX 是无需刷新页面就能够从服务器去的数据的一种方法,负责Ajax运作的核心对象是XMLHttpRequest(XHR)对象。\u003C\u002Fp\u003E\u003Cp\u003E同源策略是对XHR的一个主要约束,它为通信设置了“相同的域、相同的端口、相同的协议”这一限制。\u003Cbr\u003E试图访问上述限制之外的资源都会引发安全错误,除非采用被认可的跨域解决方案。\u003C\u002Fp\u003E\u003Cp\u003E这个方案叫做CORS(Cross-Origin Resource Sharing)跨源资源共享。\u003C\u002Fp\u003E\u003Cblockquote\u003E\u003Cp\u003E哪些访问属于跨域?\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Ehttp:\u002F\u002Fa.com\u002F 不允许访问 http:\u002F\u002Fb.com(不同域)\nhttp:\u002F\u002Fa.com 不允许访问 https:\u002F\u002Fa.com(同一域名,不同协议)\nhttp:\u002F\u002Fa.com 不允许访问 http:\u002F\u002Fa.com:8080(同一域名,不同端口)\nhttp:\u002F\u002Fa.com 不允许访问 http:\u002F\u002F192.168.1.1(域名和域名对应的ip)\nhttp:\u002F\u002Fa.a.com 不允许访问 http:\u002F\u002Fb.a.com(主域相同,子域不同)\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cblockquote\u003E\u003Cp\u003E三种解决方案:\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Cul\u003E\u003Cli\u003E\u003Cp\u003E方案一:\u003C\u002Fp\u003E\u003Cp\u003E\u002F\u002F弊端:存在浏览器兼容的问题。\u003C\u002Fp\u003E\u003Cfigure\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\u002Fpic3.zhimg.com\u002Fv2-3bbf1f5bb0ac44f649aa672fa8e2dbe4_b.jpg\& data-rawwidth=\&945\& data-rawheight=\&450\& class=\&origin_image zh-lightbox-thumb\& width=\&945\& data-original=\&https:\u002F\u002Fpic3.zhimg.com\u002Fv2-3bbf1f5bb0ac44f649aa672fa8e2dbe4_r.jpg\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='945'%20height='450'&&\u002Fsvg&\& data-rawwidth=\&945\& data-rawheight=\&450\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&945\& data-original=\&https:\u002F\u002Fpic3.zhimg.com\u002Fv2-3bbf1f5bb0ac44f649aa672fa8e2dbe4_r.jpg\& data-actualsrc=\&https:\u002F\u002Fpic3.zhimg.com\u002Fv2-3bbf1f5bb0ac44f649aa672fa8e2dbe4_b.jpg\&\u003E\u003C\u002Ffigure\u003E\u003Cp\u003E需要被请求方的服务端设置: Access-Control-Allow-Origin\u003C\u002Fp\u003E\u003Cp\u003E切记:Access-Control-Allow-Origin 不可设置为 * ,设置为可访问的域名。\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u002F\u002F设置可供访问的白名单\n$white_list = ['http:\u002F\u002Fcdn.abc.com','http:\u002F\u002Fabc.com'];\n\n$_SERVER['HTTP_ORIGIN'] \u002F\u002F表示请求方的域名\n\n$http_origin = '';\nif (!empty($_SERVER['HTTP_ORIGIN']) && in_array($_SERVER['HTTP_ORIGIN'],$white_list)) {\n
$http_origin = $_SERVER['HTTP_ORIGIN'];\n\n
\u002F\u002F设置 header 信息\n
header(\&Access-Control-Allow-Origin: {$http_origin}\&);\n
header(\&Access-Control-Allow-Methods\&, \&POST,GET\&);\n
header('Access-Control-Allow-Credentials:true');
\u002F\u002F允许访问Cookie\n
header('Access-Control-Allow-Headers : X-Requested-With'); \u002F\u002F设置Headers\n}\n\u002F\u002F执行代码逻辑...\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E另:如果请求的是html,在文件里加上meta标签。\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E&meta http-equiv=\&Access-Control-Allow-Origin\& content=\&*\&&\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E方案二:\u003C\u002Fp\u003E\u003Cp\u003E\u002F\u002F弊端:不支持 POST 请求。\u003C\u002Fp\u003E\u003Cp\u003E使用 JSONP 进行解决跨域问题,网上文章蛮多的。\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E方案三:\u003C\u002Fp\u003E\u003Cp\u003E与方案一类似。\u003C\u002Fp\u003E\u003Cp\u003E修改Nginx Apache 配置:\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u002F\u002FNginx\n\nhttp {\n
add_header Access-Control-Allow-Origin *;\n
add_header Access-Control-Allow-Headers X-Requested-W\n
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;\n
......\n}\n\nApache :\n\n&Directory \u002F&\n
Header set Access-Control-Allow-Origin *\n&\u002FDirectory&\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E大家可以根据自己的情况进行选择方案。\u003C\u002Fp\u003E\u003Cp\u003EThanks ~\u003C\u002Fp\u003E&,&updated&:new Date(&T03:58:10.000Z&),&canComment&:false,&commentPermission&:&anyone&,&commentCount&:0,&collapsedCount&:0,&likeCount&:1,&state&:&published&,&isLiked&:false,&slug&:&&,&lastestTipjarors&:[],&isTitleImageFullScreen&:false,&rating&:&none&,&titleImage&:&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-bb2b70dfe92d34a25b4e_r.jpg&,&links&:{&comments&:&\u002Fapi\u002Fposts\u002F2Fcomments&},&reviewers&:[],&topics&:[{&url&:&https:\u002F\u002Fwww.zhihu.com\u002Ftopic\u002F&,&id&:&&,&name&:&PHP 开发&},{&url&:&https:\u002F\u002Fwww.zhihu.com\u002Ftopic\u002F&,&id&:&&,&name&:&Ajax&}],&adminClosedComment&:false,&titleImageSize&:{&width&:900,&height&:500},&href&:&\u002Fapi\u002Fposts\u002F&,&excerptTitle&:&&,&column&:{&slug&:&IT-Group&,&name&:&IT小圈儿&},&tipjarState&:&activated&,&tipjarTagLine&:&恩~ 这是一个方案。&,&sourceUrl&:&&,&pageCommentsCount&:0,&tipjarorCount&:0,&annotationAction&:[],&hasPublishingDraft&:false,&snapshotUrl&:&&,&publishedTime&:&T11:58:10+08:00&,&url&:&\u002Fp\u002F&,&lastestLikers&:[{&bio&:&hello&,&isFollowing&:false,&hash&:&78f8e7d1d93&,&uid&:603800,&isOrg&:false,&slug&:&huang-jie-84-76&,&isFollowed&:false,&description&:&&,&name&:&Jitre&,&profileUrl&:&https:\u002F\u002Fwww.zhihu.com\u002Fpeople\u002Fhuang-jie-84-76&,&avatar&:{&id&:&66a1d067cc42d95ce2d817ebcc04ae0e&,&template&:&https:\u002F\u002Fpic1.zhimg.com\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false}],&summary&:&什么是AJAX?AJAX 是无需刷新页面就能够从服务器去的数据的一种方法,负责Ajax运作的核心对象是XMLHttpRequest(XHR)对象。同源策略是对XHR的一个主要约束,它为通信设置了“相同的域、相同的端口、相同的协议”这一限制。 试图访问上述限制之外的资源都会引…&,&reviewingCommentsCount&:0,&meta&:{&previous&:{&isTitleImageFullScreen&:false,&rating&:&none&,&titleImage&:&https:\u002F\u002Fpic2.zhimg.com\u002F50\u002Fv2-b088db7e453cd4b5fbd29_xl.jpg&,&links&:{&comments&:&\u002Fapi\u002Fposts\u002F2Fcomments&},&topics&:[{&url&:&https:\u002F\u002Fwww.zhihu.com\u002Ftopic\u002F&,&id&:&&,&name&:&PHP 开发&},{&url&:&https:\u002F\u002Fwww.zhihu.com\u002Ftopic\u002F&,&id&:&&,&name&:&PHP 程序员&},{&url&:&https:\u002F\u002Fwww.zhihu.com\u002Ftopic\u002F&,&id&:&&,&name&:&报警系统&}],&adminClosedComment&:false,&href&:&\u002Fapi\u002Fposts\u002F&,&excerptTitle&:&&,&author&:{&bio&:&优秀是一种品质,卓越是一种境界。&,&isFollowing&:false,&hash&:&546c8be20acff8bd1f88&,&uid&:36,&isOrg&:false,&slug&:&nick-dreamer&,&isFollowed&:false,&description&:&技术个人总结,将同步记录到公众号中。\n个人公众号:IT小圈儿\n账号:ToFeelings&,&name&:&Dreamer&,&profileUrl&:&https:\u002F\u002Fwww.zhihu.com\u002Fpeople\u002Fnick-dreamer&,&avatar&:{&id&:&f27f2e495f4&,&template&:&https:\u002F\u002Fpic2.zhimg.com\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},&column&:{&slug&:&IT-Group&,&name&:&IT小圈儿&},&content&:&\u003Cblockquote\u003EGearman 是什么?\u003C\u002Fblockquote\u003E\u003Cp\u003EGearman是一个用来把工作委派给其他机器、分布式的调用更适合做某项工作的机器、并发的做某项工作在多个调用间做负载均衡、或用来在调用其它语言的函数的系统。\u003C\u002Fp\u003E\u003Cblockquote\u003E\u003Cp\u003EGearman 工作原理\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Cul\u003E\u003Cli\u003EClient(客户端):创建一个Job。\u003C\u002Fli\u003E\u003Cli\u003EServer(服务):找到合适的Worker,把 Job 交给 Worker。\u003C\u002Fli\u003E\u003Cli\u003EWorker(工人):执行Job。\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cfigure\u003E\u003Cimg src=\&http:\u002F\u002Fpic2.zhimg.com\u002Fv2-e982e4ac03feff0d36f34dac04dfff2d_b.png\& data-rawwidth=\&532\& data-rawheight=\&330\& class=\&origin_image zh-lightbox-thumb\& width=\&532\& data-original=\&http:\u002F\u002Fpic2.zhimg.com\u002Fv2-e982e4ac03feff0d36f34dac04dfff2d_r.png\&\u003E\u003C\u002Ffigure\u003E\u003Cbr\u003E\u003Cblockquote\u003E\u003Cp\u003EWeb 中常用的场景。\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Cul\u003E\u003Cli\u003E裁剪图片,生成缩略图。\u003C\u002Fli\u003E\u003Cli\u003E文件分发(针对用户上传的文件,进行多台服务器分发)。\u003C\u002Fli\u003E\u003Cli\u003E视频转码(对上传的视频,进行转码存储)。\u003C\u002Fli\u003E\u003Cli\u003E系统报警(当系统出现问题的时候,第一时间通知相关人)。\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cblockquote\u003E\u003Cp\u003E这篇文章主要讲解 系统报警 场景\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Cp\u003E在开发系统的过程中,往往程序会出现这样,那样的问题。\u003C\u002Fp\u003E\u003Cp\u003E我们要第一时间获取错误问题,通知短信,邮件通知给相关人员。\u003C\u002Fp\u003E\u003Cp\u003E因为,短信、邮件的发送比较耗时,并发量大的情况下,会出现延时现象。\u003C\u002Fp\u003E\u003Cp\u003E所以,使用 Gearman 实现短信,邮件的异步发送。\u003C\u002Fp\u003E\u003Cblockquote\u003E\u003Cp\u003EGearman 安装的两种方式\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Cul\u003E\u003Cli\u003E\u003Cp\u003E方式一:官网推荐安装方法\u003C\u002Fp\u003E\u003Cp\u003E官网地址:\u003Ca href=\&http:\u002F\u002Flink.zhihu.com\u002F?target=http%3A\u002F\u002Fgearman.org\u002Fgetting-started\u002F\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EGetting Started [Gearman Job Server]\u003C\u002Fa\u003E\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Eyum install gearmand\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E方式二:自定义安装\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E\u003Cp\u003E安装libevent:\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Ewget get https:\u002F\u002Fgithub.com\u002Flibevent\u002Flibevent\u002Freleases\u002Fdownload\u002Frelease-2.0.22-stable\u002Flibevent-2.0.22-stable.tar.gz\n\ntar zxvf libevent-2.0.22-stable.tar.gz\n\n.\u002Fconfigure --prefix=\u002Fusr\n\nmake && make install\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E安装Gearman server and library:\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Ewget get https:\u002F\u002Flaunchpad.net\u002Fgearmand\u002F1.2\u002F1.1.12\u002F+download\u002Fgearmand-1.1.12.tar.gz\n\ntar zxvf gearmand-1.1.12.tar.gz\n\ncd gearmand-1.1.12\n\n.\u002Fconfigure\n\n如果报错:configure: error: could not find boost\n\nyum install -y boost boost-devel\n\n如果报错:configure: error: could not find gperf\n\nyum install gperf\n\n如果报错:configure: error: Unable to find libuuid\n\nyum install libuuid-devel\n\nmake && make install\n\n安装成功后,执行 gearmand -V 查询版本号。\n\ngearmand -d 开启服务。\n\n温馨提示:\n仅供参考,遇到不可预测的问题,请进行Google。\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E安装Gearman PHP extension:\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Ewget get http:\u002F\u002Fpecl.php.net\u002Fget\u002Fgearman-1.1.2.tgz\n\ntar zxvf gearman-1.1.2.tgz\n\ncd gearman-1.1.2\n\n\u002Fusr\u002Flocal\u002Fphp\u002Fbin\u002Fphpize\n\n.\u002Fconfigure --with-php-config=\u002Fusr\u002Flocal\u002Fphp\u002Fbin\u002Fphp-config --with-gearman\n\n如果报错:configure: error: Please install libgearman\n\nyum install -y libgearman-devel.x86_64\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cblockquote\u003E\u003Cp\u003E案例(系统报警)\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Cul\u003E\u003Cli\u003E开启服务\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Egearmand -d\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cul\u003E\u003Cli\u003E执行Worker\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Ephp worker.php\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cul\u003E\u003Cli\u003Eclient.php\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E&?php\n\u002F\u002F设置错误处理器\nset_error_handler('errorHandler');\n\n\u002F\u002F在脚本结束时运行的函数\nregister_shutdown_function('fatalErrorHandler');\n\n\u002F\u002F这里发生一个警告错误,被errorHandler 捕获\n$a = $b;\n\n\u002F\u002F发生致命错误,脚本停止运行触发 fatalErrorHandler\n$c = new Test();\n\n\u002F**\n * 错误处理\n * @param int
错误代码\n * @param string $err_msg
错误信息\n * @param string $err_file
错误文件\n * @param int
错误行号\n * @param int
$is_fatal_error 是否为致命错误\n * @return string\n *\u002F\nfunction errorHandler($err_no = 0, $err_msg = '', $err_file = '', $err_line = 0, $is_fatal_error = 0)\n{\n
$strEmailInfo = ($is_fatal_error == 1) ? \&【致命错误】\\n\& : \&【警告错误】\\n\&;\n\n
$strEmailInfo .= \&时间:\&.date('Y-m-d H:i:s').\&\\n\&;\n
$strEmailInfo .= \&错误代码:{$err_no}\\n\&;\n
$strEmailInfo .= \&错误信息:{$err_msg}\\n\&;\n
$strEmailInfo .= \&错误文件:{$err_file}\\n\&;\n
$strEmailInfo .= \&错误行号:{$err_line}\\n\&;\n\n
$strSmsInfo = \&[致命错误]错误代码:{$err_no},错误信息:{$err_msg},错误文件:{$err_file}\&;\n\n
$client= new GearmanClient();\n
$client-&addServer(\&127.0.0.1\&, 4730);\n
$client-&doNormal(\&send_mail\&, $strEmailInfo);\n
if ($is_fatal_error == 1) {\n
$client-&doNormal(\&send_sms\&, $strSmsInfo);\n
}\n}\n\n\u002F**\n * 捕捉致命错误\n * @return string\n *\u002F\nfunction fatalErrorHandler() {\n
$e = error_get_last();\n
switch ($e['type']) {\n
errorHandler($e['type'], $e['message'], $e['file'], $e['line'], 1);\\n
}\n}\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cul\u003E\u003Cli\u003Eworker.php\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E&?php\n
$worker = new GearmanWorker();\n
$worker-&addServer(\&127.0.0.1\&, 4730);\n
$worker-&addFunction(\&send_mail\&, \&doSendMail\&);\n
$worker-&addFunction(\&send_sms\&, \&doSendSms\&);\n
while ($worker-&work());\n\n
\u002F**\n
* 执行发送邮件的Job\n
* @param $job\n
* @return string\n
function doSendMail($job)\n
$strEmailInfo = $job-&workload();\n\n
\u002F**\n
* 在这个方法里完善发送邮件的操作\n
* ......\n
* Demo是把信息写入到文件中\n
*\u002F\n\n
return file_put_contents(\&gearman.txt\&, $strEmailInfo.\&\\n\&, FILE_APPEND);\n
\u002F**\n
* 执行发送短信的Job\n
* @param $job\n
* @return string\n
function doSendSms($job)\n
$strSmsInfo = $job-&workload();\n\n
\u002F**\n
* 在这个方法里完善发送短信的操作\n
* ......\n
* Demo是把信息写入到文件中\n
*\u002F\n\n
return file_put_contents(\&gearman.txt\&, $strSmsInfo.\&\\n\&, FILE_APPEND);\n
}\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cul\u003E\u003Cli\u003Egearman.txt\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E【警告错误】\n时间: 23:15:10\n错误代码:8\n错误信息:Undefined variable: b\n错误文件:\u002Fhome\u002Fwww\u002Fmi\u002Fgearman\u002Fclient.php\n错误行号:9\n\n【致命错误】\n时间: 23:15:10\n错误代码:1\n错误信息:Class 'Test' not found\n错误文件:\u002Fhome\u002Fwww\u002Fmi\u002Fgearman\u002Fclient.php\n错误行号:12\n\n[致命错误]错误代码:1,错误信息:Class 'Test' not found,错误文件:\u002Fhome\u002Fwww\u002Fmi\u002Fgearman\u002Fclient.php\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cblockquote\u003E\u003Cp\u003E温馨提示\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Cul\u003E\u003Cli\u003E也可以用 Redis Queue 来实现上面的需求。\u003C\u002Fli\u003E\u003Cli\u003E也可以用 Swoole 来实现上面的需求。\u003C\u002Fli\u003E\u003Cli\u003E也可以了解下 Gearman 与 Swoole 的区别。\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cbr\u003E\u003Cp\u003EThanks ~\u003C\u002Fp\u003E&,&state&:&published&,&sourceUrl&:&&,&pageCommentsCount&:0,&canComment&:false,&snapshotUrl&:&&,&slug&:,&publishedTime&:&T10:51:25+08:00&,&url&:&\u002Fp\u002F&,&title&:&利用 Gearman 实现系统错误报警功能&,&summary&:&Gearman 是什么?Gearman是一个用来把工作委派给其他机器、分布式的调用更适合做某项工作的机器、并发的做某项工作在多个调用间做负载均衡、或用来在调用其它语言的函数的系统。Gearman 工作原理Client(客户端):创建一个Job。Server(服务):找到合适的Work…&,&reviewingCommentsCount&:0,&meta&:{&previous&:null,&next&:null},&commentPermission&:&anyone&,&commentsCount&:0,&likesCount&:1},&next&:{&isTitleImageFullScreen&:false,&rating&:&none&,&titleImage&:&https:\u002F\u002Fpic3.zhimg.com\u002F50\u002Fv2-100c081ad30bf7b84d80c5bb966e82f5_xl.jpg&,&links&:{&comments&:&\u002Fapi\u002Fposts\u002F2Fcomments&},&topics&:[{&url&:&https:\u002F\u002Fwww.zhihu.com\u002Ftopic\u002F&,&id&:&&,&name&:&PHP 开发&},{&url&:&https:\u002F\u002Fwww.zhihu.com\u002Ftopic\u002F&,&id&:&&,&name&:&PHP 程序员&},{&url&:&https:\u002F\u002Fwww.zhihu.com\u002Ftopic\u002F&,&id&:&&,&name&:&密码加密&}],&adminClosedComment&:false,&href&:&\u002Fapi\u002Fposts\u002F&,&excerptTitle&:&&,&author&:{&bio&:&优秀是一种品质,卓越是一种境界。&,&isFollowing&:false,&hash&:&546c8be20acff8bd1f88&,&uid&:36,&isOrg&:false,&slug&:&nick-dreamer&,&isFollowed&:false,&description&:&技术个人总结,将同步记录到公众号中。\n个人公众号:IT小圈儿\n账号:ToFeelings&,&name&:&Dreamer&,&profileUrl&:&https:\u002F\u002Fwww.zhihu.com\u002Fpeople\u002Fnick-dreamer&,&avatar&:{&id&:&f27f2e495f4&,&template&:&https:\u002F\u002Fpic2.zhimg.com\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},&column&:{&slug&:&IT-Group&,&name&:&IT小圈儿&},&content&:&\u003Cblockquote\u003E\u003Cp\u003E单向散列加密\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Cp\u003E单向散列加密就是把任意长的输入消息串变化成固定长的输出串且由输出串难以得到输入串的一种加密算法。\u003C\u002Fp\u003E\u003Cp\u003E常见单向散列函数:\u003Cbr\u003E- MD5 (Message Digest Algorithm 5)\u003Cbr\u003E- SHA (Secure Hash Algorithm)\u003Cbr\u003E- MAC (Message Authentication Code)\u003Cbr\u003E- CRC (Cyclic Redundancy Check)\u003C\u002Fp\u003E\u003Cp\u003E利用单项散列加密的这个特性,可以进行密码加密保存。\u003C\u002Fp\u003E\u003Cp\u003EPHP 处理密码的几种方式\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E\u003Cp\u003EMD5(不推荐)\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E$password = md5($_POST[\&password\&]);\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E原因:加密算法比较简单,而且很多破解密码的站点都存放了大量的经过MD5加密的密码字符串。\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003ESHA256 和 SHA512(不推荐)\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E$password = hash(\&sha256\&, $password);\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E原因:加密算法比较简单。\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E盐值(额外字符串)(常用)\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E&?php\n$strSalt = '2f9c8d7h6g7f8d9k';\necho hash(\&sha256\&, $password . $strSalt);\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E解释:在加密的过程中,新增了一个字符串。\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003EBcrypt (比较安全)\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E$strSalt = '2f9c8d7h6g7f8d9k';\n$salt = '$2y$11$' . $strS\necho crypt($password, $salt);\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E解释:salt 参数是可选的。然而,如果没有salt的话,crypt()创建出来的会是弱密码。\u003C\u002Fp\u003E\u003Cp\u003EPHP函数:\u003Ca href=\&http:\u002F\u002Flink.zhihu.com\u002F?target=http%3A\u002F\u002Fphp.net\u002Fmanual\u002Fzh\u002Ffunction.crypt.php\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EPHP: crypt - Manual\u003C\u002Fa\u003E\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003Epassword_hash (安全)\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u002F\u002F支持版本 (PHP 5 &= 5.5.0, PHP 7)\necho password_hash($password, PASSWORD_DEFAULT);\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E解释:password_hash() 使用足够强度的单向散列算法创建密码的哈希(hash)。\u003C\u002Fp\u003E\u003Cp\u003EPHP函数:\u003Ca href=\&http:\u002F\u002Flink.zhihu.com\u002F?target=http%3A\u002F\u002Fphp.net\u002Fmanual\u002Fzh\u002Ffunction.password-hash.php\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EPHP: password_hash\u003C\u002Fa\u003E\u003C\u002Fp\u003E\u003Cp\u003EPHP端验证密码是否正确?\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E$password = 'e4r3t2y1u';\n$strPwdHash = password_hash($password, PASSWORD_DEFAULT);\nif (password_verify($password, $strPwdHash)) {\n
\u002F\u002F验证成功\n} else {\n
\u002F\u002F验证失败\n}\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cblockquote\u003E\u003Cp\u003E对称加密\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Cp\u003E采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密。\u003C\u002Fp\u003E\u003Cp\u003E优点:对称加密算法的优点是算法公开、计算量小、加密速度快、加密效率高。\u003C\u002Fp\u003E\u003Cp\u003E缺点:在数据传送前,发送方和接收方必须商定好秘钥,双方必须保存好秘钥。\u003C\u002Fp\u003E\u003Cp\u003E常用算法:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003EDES\u003C\u002Fli\u003E\u003Cli\u003EAES\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003EPHP 相关类库,网上都能找到。\u003C\u002Fp\u003E\u003Cblockquote\u003E\u003Cp\u003E非对称加密\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Cp\u003E非对称加密算法需要两个密钥来进行加密和解密,这两个秘钥是公开密钥(public key,简称公钥)和私有密钥(private key,简称私钥)。\u003C\u002Fp\u003E\u003Cp\u003E请查看历史文章:\u003Ca href=\&http:\u002F\u002Flink.zhihu.com\u002F?target=http%3A\u002F\u002Fmp.weixin.qq.com\u002Fs%3F__biz%3DMjM5NDM4MDIwNw%3D%3D%26mid%3D%26idx%3D1%26sn%3D1da3dd95cb0823bca9034bdaf715a27b%23rd\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EPHP 使用非对称加密算法 (RSA)\u003C\u002Fa\u003E\u003C\u002Fp\u003E\u003Cblockquote\u003E\u003Cp\u003E密钥安全管理\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Cp\u003E上面说到的这几种加密技术,能够达到安全保密效果的一种重要前提就是密钥的安全。\u003C\u002Fp\u003E\u003Cp\u003E在实际工作中,我们有开发环境,预发布环境,正式环境,每个环境中的密钥都不相同。\u003C\u002Fp\u003E\u003Cp\u003E那么,我们应该如何保存密钥呢?\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E写在源码中(不可取)。\u003C\u002Fli\u003E\u003Cli\u003E写在配置文件中。(大部分这样干)。\u003C\u002Fli\u003E\u003Cli\u003E写在环境变量中。(大部分这样干)。\u003C\u002Fli\u003E\u003Cli\u003E保存在一个系统中,每次加密、解密都调取服务系统(系统开销大)。\u003C\u002Fli\u003E\u003Cli\u003E自己写一个扩展,用PHP调取自己的扩展(维护成本高)。\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E暂时就想到这么多,望大神提供新的思路~\u003C\u002Fp\u003E\u003Cp\u003EThanks ~\u003C\u002Fp\u003E&,&state&:&published&,&sourceUrl&:&&,&pageCommentsCount&:0,&canComment&:false,&snapshotUrl&:&&,&slug&:,&publishedTime&:&T09:55:10+08:00&,&url&:&\u002Fp\u002F&,&title&:&数据加密技术与密钥安全管理&,&summary&:&单向散列加密单向散列加密就是把任意长的输入消息串变化成固定长的输出串且由输出串难以得到输入串的一种加密算法。常见单向散列函数: - MD5 (Message Digest Algorithm 5) - SHA (Secure Hash Algorithm) - MAC (Message Authentication Code) - CR…&,&reviewingCommentsCount&:0,&meta&:{&previous&:null,&next&:null},&commentPermission&:&anyone&,&commentsCount&:0,&likesCount&:2}},&annotationDetail&:null,&commentsCount&:0,&likesCount&:1,&FULLINFO&:true}},&User&:{&nick-dreamer&:{&isFollowed&:false,&name&:&Dreamer&,&headline&:&技术个人总结,将同步记录到公众号中。\n个人公众号:IT小圈儿\n账号:ToFeelings&,&avatarUrl&:&https:\u002F\u002Fpic2.zhimg.com\u002Ff27f2e495f4_s.jpg&,&isFollowing&:false,&type&:&people&,&slug&:&nick-dreamer&,&bio&:&优秀是一种品质,卓越是一种境界。&,&hash&:&546c8be20acff8bd1f88&,&uid&:36,&isOrg&:false,&description&:&技术个人总结,将同步记录到公众号中。\n个人公众号:IT小圈儿\n账号:ToFeelings&,&badge&:{&identity&:null,&bestAnswerer&:null},&profileUrl&:&https:\u002F\u002Fwww.zhihu.com\u002Fpeople\u002Fnick-dreamer&,&avatar&:{&id&:&f27f2e495f4&,&template&:&https:\u002F\u002Fpic2.zhimg.com\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false}},&Comment&:{},&favlists&:{}},&me&:{},&global&:{&experimentFeatures&:{&ge3&:&ge3_9&,&ge2&:&ge2_1&,&growthSearch&:&s0&,&nwebQAGrowth&:&experiment&,&qawebRelatedReadingsContentControl&:&open&,&marketTabBanner&:&market_tab_banner_show&,&liveStore&:&ls_a2_b2_c1_f2&,&qawebThumbnailAbtest&:&new&,&nwebSearch&:&nweb_search_heifetz&,&enableVoteDownReasonMenu&:&enable&,&showVideoUploadAttention&:&true&,&isOffice&:&false&,&enableTtsPlay&:&post&,&newQuestionDiversion&:&true&,&wechatShareModal&:&wechat_share_modal_show&,&newLiveFeedMediacard&:&old&,&androidPassThroughPush&:&all&,&hybridZhmoreVideo&:&no&,&nwebGrowthPeople&:&default&,&nwebSearchSuggest&:&default&,&qrcodeLogin&:&qrcode&,&androidDbFollowRecommendHide&:&open&,&isShowUnicomFreeEntry&:&unicom_free_entry_off&,&newMobileColumnAppheader&:&new_header&,&androidDbCommentWithRepinRecord&:&open&,&feedHybridTopicRecomButtonIcon&:&yes&,&androidDbRecommendAction&:&open&,&zcmLighting&:&zcm&,&androidDbFeedHashTagStyle&:&button&,&appStoreRateDialog&:&close&,&topWeightSearch&:&new_top_search&,&default&:&None&,&isNewNotiPanel&:&no&,&androidDbRepinSelection&:&open&,&growthBanner&:&default&,&androidProfilePanel&:&panel_b&}},&columns&:{&next&:{},&IT-Group&:{&following&:false,&canManage&:false,&href&:&\u002Fapi\u002Fcolumns\u002FIT-Group&,&name&:&IT小圈儿&,&creator&:{&slug&:&nick-dreamer&},&url&:&\u002FIT-Group&,&slug&:&IT-Group&,&avatar&:{&id&:&v2-f75b94eb56ceecfa96117b5&,&template&:&https:\u002F\u002Fpic1.zhimg.com\u002F{id}_{size}.jpg&}}},&columnPosts&:{},&columnSettings&:{&colomnAuthor&:[],&uploadAvatarDetails&:&&,&contributeRequests&:[],&contributeRequestsTotalCount&:0,&inviteAuthor&:&&},&postComments&:{},&postReviewComments&:{&comments&:[],&newComments&:[],&hasMore&:true},&favlistsByUser&:{},&favlistRelations&:{},&promotions&:{},&switches&:{&couldSetPoster&:false},&draft&:{&titleImage&:&&,&titleImageSize&:{},&isTitleImageFullScreen&:false,&canTitleImageFullScreen&:false,&title&:&&,&titleImageUploading&:false,&error&:&&,&content&:&&,&draftLoading&:false,&globalLoading&:false,&pendingVideo&:{&resource&:null,&error&:null}},&drafts&:{&draftsList&:[],&next&:{}},&config&:{&userNotBindPhoneTipString&:{}},&recommendPosts&:{&articleRecommendations&:[],&columnRecommendations&:[]},&env&:{&edition&:{&baidu&:false,&yidianzixun&:false,&qqnews&:false},&isAppView&:false,&appViewConfig&:{&content_padding_top&:128,&content_padding_bottom&:56,&content_padding_left&:16,&content_padding_right&:16,&title_font_size&:22,&body_font_size&:16,&is_dark_theme&:false,&can_auto_load_image&:true,&app_info&:&OS=iOS&},&isApp&:false,&userAgent&:{&ua&:&Mozilla\u002F5.0 (compatible, MSIE 11, Windows NT 6.3; Trident\u002F7.0; rv:11.0) like Gecko&,&browser&:{&name&:&IE&,&version&:&11&,&major&:&11&},&engine&:{&version&:&7.0&,&name&:&Trident&},&os&:{&name&:&Windows&,&version&:&8.1&},&device&:{},&cpu&:{}}},&message&:{&newCount&:0},&pushNotification&:{&newCount&:0}}

我要回帖

更多关于 ajax解决跨域问题 的文章

 

随机推荐