文章加密

;

2018年11月29日 星期四

$_SERVER['REMOTE_ADDR'], 抓使用者IP

$_SERVER['REMOTE_ADDR'] 會抓到 真實該本人位置 或 代理伺服器Proxy 的IP。

所謂代理伺服器Proxy是A,B,C三人都從台灣各地要去瀏覽美國某網站,因為距離很遠,網路連接時會通過海纜,但海纜寬頻有限,這時中華電信就會用代理伺服器Proxy(也就是某主機)紀錄A去看完留下的網路內容,當B又要連結該內容,B不需要再通過海纜去到外國,只要從Proxy抓取該網路內容,即可。
中華電信並不一定要用代理伺服器Proxy,只是通常會這樣做。

如果距離很近/不需要用到Proxy,則就能抓到他的真實IP,或殭屍主機(駭客才會用的)。




代理快取伺服器的技術中大致分類為"正向代理(Proxy)快取"與"反向代理(Reverse Proxy)快取"兩種快取技術。

現行較為主流的反向代理技術逐漸取代了正向代理技術,主要原因就是反向代理技術由網站方加設,便能提供大眾使用者的便利,而其所主要應用的技術為 "內容傳遞網路-CDN(Content delivery network)"。




  • $_SERVER['HTTP_CLIENT_IP']这个头是有的,但是很少,不一定服务器都实现了。客户端可以伪造。
  • $_SERVER['HTTP_X_FORWARDED_FOR'] 當今多數快取伺服器的使用者為大型ISP,為了通過快取的方式來降低他們的外部頻寬,他們常常通過鼓勵或強制用戶使用代理伺服器來接入網際網路。有些情況下,這些代理伺服器是透明代理,用戶甚至不知道自己正在使用代理上網。
    它是有标准定义,用来识别经过HTTP代理后的客户端IP地址,格式:
    clientip,proxy1,proxy2。详细解释见 http://zh.wikipedia.org/wiki/X-Forwarded-For。 客户端可以伪造。算是個約定成俗的會添加在header裡的meta標籤中,雖然沒有硬性規定必須。
  • $_SERVER['REMOTE_ADDR'] 是可靠的, 它是最后一个跟你的服务器握手的IP,可能是用户的代理服务器,也可能是自己的反向代理。客户端不能伪造。
    客户端可以伪造的参数必须过滤和验证!很多人以为$_SERVER变量里的东西都是可信的,其实并不不然,$_SERVER['HTTP_CLIENT_IP']$_SERVER['HTTP_X_FORWARDED_FOR']都来自客户端请求的header里面。

2018年11月25日 星期日

vip1結束時的心得

混亂的第一次嘗試,各種的以為有的限制或以為要做成的結果,以及最後為了補救之前浪費的時間,在已寫成的有偏差的程式中直接補丁,導致寫出的程式有幾處不順眼,以下列出:


  1. 我不應該侷限於GET或POST的方式讓後端接資料,還應該有讓後端include我專門處理資料的php檔案(以下命名為deal.php)。例如使用者click第三頁,先GET傳送page=3的參數到deal.php,處理算出後端真正需要的"要略過的筆數($offset)",然後後端include "deal.php",就取得了$offset。
  2. 最後測試時才發現disabled仍會送出,應該再仔細點
其他純心得:
  1. 金流、獎金規範的計算關係到程式的設定,應該最初就確認好,製作時就不會再反覆的修改。也就是在開始製作前,應該先規劃確認每一個操作。
  2. 在與後端合作時,因為這次不是用API,所以有機會再學習了一把php
  3. php寫的就不會被user改,除了cookie,因為有cookie這個檔案。$_GET、$_POST本來就是接收使用者方面的,所以會被改也無法,後端本來就要再去防。其他我能在前端做成後端要的最根本的值,那就在前端做吧!後端撈資料、join, alter等各種的操縱資料庫...就很麻煩了。目前所知能做的有分頁傳筆數,那其他還有??
  4. 對於真正的工程師生活作息似乎了解了一點。

php是template lauguage

The premise behind a template language is that the language is "embedded" within some other master document. Specifically, on your average document, the total size of the document is mostly document source than template language.

Some template languages are full blown general purpose languages, such as PHP, ASP.NET, and Java's JSP. Others are more limited designed specifically for templating, such as Velocity and FreeMarker (both utilities for Java).
Many word processors, such as Microsoft Word, have their own templating capabilities, commonly referred to as "Mail Merge".

2018年11月22日 星期四

後端想要前端傳入的是一組array數據

後端想要前端傳入的是一組array數據,那先個別的post到php,再用php取組成(前端可做),前端form最多a[],不要寫到a[][],也不要再[]裡寫文字!

2018年11月21日 星期三

搜索網站客戶人數等等資訊分析 similarweb alexa

https://www.similarweb.com/

https://www.alexa.com/   這個似乎要加入會員

用php取得使用者端ip server clientip

https://stackoverflow.com/questions/15699101/get-the-client-ip-address-using-php

input type="number",input list="XXX"搭配 datalist id="XXX"(父), option各種選項(子)

使用input type="number"

  1. 会自动验证你输入的文本是否为数字
  2. 可以搭配placeholder="multiple of 10" step="10" min="0" max="100" value="10"(有placeholder就不要有value,二選一)(placeholder被稱為占位符)
  3. 移动浏览器通过在用户尝试输入值时显示更适合输入数字的特殊键盘,进一步帮助用户体验。
  4. 如果輸入的不適規範的數值,瀏覽器會顯示錯誤訊息給使用者(錯誤訊息例如:請輸入有效值。最接近的兩個有效值分別是30和40)

其中step設10,在手動輸入15,雖然畫面顯示上是可以,但其實是無效的。
如果要小數把step設小數即可,如step="0.01"。
调整输入框的宽度为仅可输入3位数字的宽度,在css添加width: 3em;
datalist id="XXX"(父), option各種選項(子),類似select option,但在選定某一個option後,要改選項須先鍵盤delete原本的值,想像一下似乎datalist適合用在移動端(但真的需要嗎?再觀察),不適合用在電腦端。
添加required則該input傳送資料時不能為空值
再css裡可以用input:invalid, :valid, and :required 選擇元素

2018年11月20日 星期二

做登入時,cookie或session blabla ※php程式是不會因為在使用者端執行而能被使用者更改的,cookie是特例,因為他有個file存在client端

#cookie
如果儲存登入資料在使用者cookie file裡面,當使用者下載到病毒時,病毒程式碼盜取cookie file就獲得了username和password,即使先加密再存成cookie,盜取者依然可用加密的結果登入。

解法:不存任何使用者端的東西,cookie儲存後端確認帳號密碼正確後吐回的東西,通常後端會根據使用者的id, ip, token(隨機生成), date生成登入資料,儲存在資料庫,吐回的東西裡地理ip難以偽造,所以即使cookie被盜也無妨

缺點:如果使用者關閉cookie(隱私意識抬頭),它就無法登入網站了,需指示使用者開啟cookie。(在google與facebook測試皆是如此)

用於「前端和Class在一起」以及「前端接API」

#session
缺點:無法記錄登入狀態,每次都要重新登入,當使用者關閉網站或斷線後,伺服器session file會自動刪除

只用於「前端和Class在一起」

2018年11月12日 星期一

form表單傳php不要用array型式。form表單裡用button它會自動作為提交的動作,想要按下而不自動變化,用div。form用input type=file時,和一般的不同,ajax裡不能再用serialize,要改用FormData

因為

php要的格式
$jsonA = array(
'app' => 'vip',
'func' => 'new',
'para' => array(
'level' => '1',
'upstand' => '1',
'upaward' => '1',
'weekstand' => '1',
'monthstand' => '1',
'weekaward' => '1',
'monthaward' => '1'
)
);

javascript傳過去的格式
Array
(
    ['app'] => vip
    ['func'] => new
    ['para'] => Array
        (
            ['level'] =>
            ['upstand'] =>
            ['upaward'] =>
            ['weekstand'] => 4
            ['monthstand'] =>
            ['weekaward'] =>
            ['monthaward'] =>
        )

)
兩種用php的gettype都是array
但是javascript的(我先給它儲存到$a變數中),$a['app']會出現錯誤,$a["app"]是undefine index app,要寫成$a["'"."app"."'"]才會是vip
這就要說到php基礎章:
$b=21;
echo '$b'; //$b
echo "$b"; //21
總之就是格式的問題,雖然兩者型態都是array,但仍然不能順利地使用,最後總結不用array傳,用單個單個的傳,再用for迴圈在php組成array使用。
另外再組成前也還可添加判斷接收到的數據是啥 blabla的程式

2018年11月4日 星期日

=> arrow function 與 addEventListener, cancelable

https://stackoverflow.com/questions/24900875/whats-the-meaning-of-an-arrow-formed-from-equals-greater-than-in-javas

1. they do not bind their own values of this
2. Arrow functions are always anonymous.  即function foo(){}
3. Arrow functions are part of the ECMAscript 6 specification, but not part of "normal" JavaScript in use in most browsers today. 

in place of expressions like function (foo) {...}, you can see below:
例1
var a = [
  "We're up all night 'til the sun",
  "We're up all night to get some",
  "We're up all night for good fun",
  "We're up all night to get lucky"
];

// These two assignments are equivalent:

// Old-school:
var a2 = a.map(function(s){ return s.length });

// ECMAscript 6 using arrow functions
var a3 = a.map( s => s.length );

// both a2 and a3 will be equal to [31, 30, 31, 31]

例2
function Foo() {
    this.name = name;
    this.count = 0;
    this.startCounting();
}

Foo.prototype.startCounting = function() {
  var self = this;
  setInterval(function () {
    // this is the Window, not Foo {}, as you might expect
    console.log(this); // [object Window]
    // that's why we reassign this to self before setInterval()
    console.log(self.count);
    self.count++;
  },1000)
}

new Foo();
可寫成
function Foo() {
    this.name = name;
    this.count = 0;
    this.startCounting();
}

Foo.prototype.startCounting = function() {
  setInterval(() => {        
    console.log(this); // [object Object]
    console.log(this.count); // 1, 2, 3
    this.count++;
  },1000)
}

new Foo();




https://blog.techbridge.cc/2017/07/15/javascript-event-propagation/


1. 關於這些事件的傳遞順序,只要記住兩個原則就好:


先捕獲,再冒泡
當事件傳到 target 本身,沒有分捕獲跟冒泡

2.eventPhase,是一個數字,表示這個事件在哪一個 Phase 觸發。
html:
// PhaseType
const unsigned short CAPTURING_PHASE = 1;
const unsigned short AT_TARGET = 2;
const unsigned short BUBBLING_PHASE = 3;

3.實例說明

<!DOCTYPE html>
<html>
<body>
<ul id="list">
<li id="list_item">
<a id="list_item_link" target="_blank" href="http://google.com">
</a>
</li>
</ul>
</body>
</html>
js:
const get = (id) => document.getElementById(id);
const $list = get('list');
const $list_item = get('list_item');
const $list_item_link = get('list_item_link');
// list 的冒泡
$list.addEventListener('click', (e) => {
console.log('list bubbling', e.eventPhase);
}, false)
// list 的捕獲
$list.addEventListener('click', (e) => {
console.log('list capturing', e.eventPhase);
}, true)
// list_item 的冒泡
$list_item.addEventListener('click', (e) => {
console.log('list_item bubbling', e.eventPhase);
}, false)
// list_item 的捕獲
$list_item.addEventListener('click', (e) => {
console.log('list_item capturing', e.eventPhase);
}, true)
// list_item_link 的冒泡
$list_item_link.addEventListener('click', (e) => {
console.log('list_item_link bubbling', e.eventPhase);
}, false)
// list_item_link 的捕獲
$list_item_link.addEventListener('click', (e) => {
console.log('list_item_link capturing', e.eventPhase);
}, true)

一樣點擊超連結,輸出的結果是:
list capturing 1
list_item capturing 1
list_item_link bubbling 2
list_item_link capturing 2
list_item bubbling 3
list bubbling 3


4. 事件鏈這麼長,一定有方法可以中斷這一條鏈,讓事件的傳遞不再繼續,就是:e.stopPropagation (取消事件傳遞),但對於同一個層級,其他的 listener 還是會被執行到。

若是你想要讓其他同一層級的 listener 也不要被執行,可以改用e.stopImmediatePropagation();

5. e.preventDefault (取消預設行為) ,preventDefault跟 JavaScript 的事件傳遞「一點關係都沒有」,你加上這一行之後,事件還是會繼續往下傳遞。

Once preventDefault has been called it will remain in effect throughout the remainder of the event’s propagation. 意思就是說一旦 call 了preventDefault,在之後傳遞下去的事件裡面也會有效果。

以上面的例子,$list改寫成下方這樣,則不會跳出google.com新頁面,但所有console.log內容都會和原本所呈現的結果一樣
// list 的捕獲
$list.addEventListener('click', (e) => {
console.log('list capturing', e.eventPhase);
e.preventDefault();
}, true)


應用 做數據統計及分析










1
2
3
window.addEventListener('click', (e) => {
console.log(e.target);
}, true)
利用事件傳遞機制的特性,在window上面使用捕獲,就能保證一定是第一個被執行的事件,你就可以在這個 function 裡面偵測頁面中每一個元素的點擊,可以傳回去做數據統計及分析。




cancelable動作:檢測事件是否為 preventDefault() 方法可以取消与事件关联的默认动作 ,結果會回傳true, 或false。所有 Cancelable 为 true 的事件类型理论上都是可以有 {passive: true} 优化的。

passive: addEventListener() 的第三个参数之一,出現這個參數的理由是 浏览器无法预先知道一个监听器会不会调用 preventDefault(),它能做的只有等监听器执行完后再去执行默认行为,而监听器执行是要耗时的,有些甚至耗时很明显,这样就会导致页面卡顿
passive 的意思是“顺从的”,表示它不会对事件的默认行为说 no,也就是 preventDefault() 无效。
鉴于这个新特性本来就是为解决滚动和触摸事件的卡顿而发明的,目前 Chrome 和 Firefox 支持优化的事件类型也仅限这类事件,比如 touchstart,touchmove,wheel 等事件。
即便为下面这些类型的事件添加 passive 的监听器,目前浏览器们也不会优化:
  • click 事件: 左键点击这个链接,等待 3 秒后才会打开新页面(可能被浏览器识别成弹窗)
  • contextmenu 事件:右键点击这句文本,等待 3 秒后才会打开右键菜单 
  • beforeinput 事件(只有 Chrome 52 及以上支持):在右侧输入时会有 300 毫秒的卡顿 
总结一下就是 {passive: true} 不能保证浏览器对所有事件类型的默认行为进行优化

http://www.cnblogs.com/ziyunfei/p/5545439.html

event.defaultPrevented:

回傳一個布林值,表示事件的預設行為是否被取消,也就是事件物件是否曾執行 preventDefault() 方法

event.stopPropagation():stops the move upwards, but on the current element all other handlers will run.
event.stopImmediatePropagation():stop the bubbling and prevent handlers on the current element from running.

dispatchEvent:是「建立→初始化→觸發」的最後一步驟。而事件有多種建立方式,例如用 ​document.createEvent 並用 initEvent 或其他特殊 methods ,像是 initMouseEvent 或 initUIEvent 來初始化。
或是用new Event建立,再用addEventListener監聽,最後再用dispatchEvent觸發。
也就是說,欲使用dispatchEvent必須要有一定的前置作業!

綜合上述各個新詞彙,應用如下
let event = new Event("foo", {  // 创建一个 type 为 foo 的事件对象,可以被阻止默认行为。這是創建了一個叫foo的「動作」!
  "cancelable": true
})

document.addEventListener("foo", function(event) { // 在 document 上绑定 foo 事件的监听函数。為了更熟悉,可以想像foo替換成click,這樣就是監聽click動作
  console.log(event.defaultPrevented) // false
  event.preventDefault()
  console.log(event.defaultPrevented) // 还是 false,preventDefault() 无效
}, {
  passive: true
})
 
document.dispatchEvent(event) // 觸發自定义事件

輸出結果會有 Unable to preventDefault inside passive event listener invocation.警告

另外,我們要注意:event.currentTarget (=this) v.s. event.target(触发事件的元素,觀念為caturing→target→bubbling) 
currentTarget有可能會比較大,為parent element。
而target會是特定element,不會是parent element。

在 removeEventListener 的时候永远不需写 passive 和 once,但 capture 可能要!理由显而易见,一个监听器同时是 passive 和非 passive(以及同时是 once 和非 once)是说不通的,如果你添加了两者,那么后添加的不算,浏览器会认为添加过了