Ecoer Logo
VOTING POWER100.00%
DOWNVOTE POWER100.00%
RESOURCE CREDITS100.00%
REPUTATION PROGRESS66.51%
Net Worth
0.229USD
STEEM
0.001STEEM
SBD
0.379SBD
Effective Power
5.001SP
├── Own SP
0.778SP
└── Incoming Deleg
+4.223SP

Detailed Balance

STEEM
balance
0.001STEEM
market_balance
0.000STEEM
savings_balance
0.000STEEM
reward_steem_balance
0.000STEEM
STEEM POWER
Own SP
0.778SP
Delegated Out
0.000SP
Delegation In
4.223SP
Effective Power
5.001SP
Reward SP (pending)
0.000SP
SBD
sbd_balance
0.379SBD
sbd_conversions
0.000SBD
sbd_market_balance
0.000SBD
savings_sbd_balance
0.000SBD
reward_sbd_balance
0.000SBD
{
  "balance": "0.001 STEEM",
  "savings_balance": "0.000 STEEM",
  "reward_steem_balance": "0.000 STEEM",
  "vesting_shares": "1267.036038 VESTS",
  "delegated_vesting_shares": "0.000000 VESTS",
  "received_vesting_shares": "6876.623768 VESTS",
  "sbd_balance": "0.379 SBD",
  "savings_sbd_balance": "0.000 SBD",
  "reward_sbd_balance": "0.000 SBD",
  "conversions": []
}

Account Info

namesemlinker
id506274
rank508,321
reputation1977531713
created2017-12-18T13:36:45
recovery_accountsteem
proxyNone
post_count23
comment_count0
lifetime_vote_count0
witnesses_voted_for0
last_post2018-01-28T15:01:30
last_root_post2018-01-28T15:01:30
last_vote_time2018-01-28T14:55:09
proxied_vsf_votes0, 0, 0, 0
can_vote1
voting_power0
delayed_votes0
balance0.001 STEEM
savings_balance0.000 STEEM
sbd_balance0.379 SBD
savings_sbd_balance0.000 SBD
vesting_shares1267.036038 VESTS
delegated_vesting_shares0.000000 VESTS
received_vesting_shares6876.623768 VESTS
reward_vesting_balance0.000000 VESTS
vesting_balance0.000 STEEM
vesting_withdraw_rate0.000000 VESTS
next_vesting_withdrawal1969-12-31T23:59:59
withdrawn0
to_withdraw0
withdraw_routes0
savings_withdraw_requests0
last_account_recovery1970-01-01T00:00:00
reset_accountnull
last_owner_update1970-01-01T00:00:00
last_account_update2017-12-22T15:22:18
minedNo
sbd_seconds675,136,569
sbd_last_interest_payment2018-01-05T04:30:27
savings_sbd_last_interest_payment1970-01-01T00:00:00
{
  "active": {
    "account_auths": [],
    "key_auths": [
      [
        "STM8iBs6jPJ8nbkJSiykDpa8wB56Wdk7FJ2gwXbeNMsfYFCGkwNPx",
        1
      ]
    ],
    "weight_threshold": 1
  },
  "balance": "0.001 STEEM",
  "can_vote": true,
  "comment_count": 0,
  "created": "2017-12-18T13:36:45",
  "curation_rewards": 0,
  "delegated_vesting_shares": "0.000000 VESTS",
  "downvote_manabar": {
    "current_mana": 2035914951,
    "last_update_time": 1779085092
  },
  "guest_bloggers": [],
  "id": 506274,
  "json_metadata": "{\"profile\":{\"profile_image\":\"https://sfault-avatar.b0.upaiyun.com/483/735/483735741-58c0cb69d67b6_big64\"}}",
  "last_account_recovery": "1970-01-01T00:00:00",
  "last_account_update": "2017-12-22T15:22:18",
  "last_owner_update": "1970-01-01T00:00:00",
  "last_post": "2018-01-28T15:01:30",
  "last_root_post": "2018-01-28T15:01:30",
  "last_vote_time": "2018-01-28T14:55:09",
  "lifetime_vote_count": 0,
  "market_history": [],
  "memo_key": "STM5AgN5T9XyVsrszQ9QWgzbVmwpBWimBGqMJwvYamaGMPhZokMRH",
  "mined": false,
  "name": "semlinker",
  "next_vesting_withdrawal": "1969-12-31T23:59:59",
  "other_history": [],
  "owner": {
    "account_auths": [],
    "key_auths": [
      [
        "STM7JVtz68DTc9viNTZcNgSJDrqKtFJH5TAicuLeWxFX6xQgdHN37",
        1
      ]
    ],
    "weight_threshold": 1
  },
  "pending_claimed_accounts": 0,
  "post_bandwidth": 0,
  "post_count": 23,
  "post_history": [],
  "posting": {
    "account_auths": [],
    "key_auths": [
      [
        "STM5sVLRTPTBYFGkt29kMDoqN6ay3QaV8W9pfRKvZkQih9Fp55FeF",
        1
      ]
    ],
    "weight_threshold": 1
  },
  "posting_json_metadata": "{\"profile\":{\"profile_image\":\"https://sfault-avatar.b0.upaiyun.com/483/735/483735741-58c0cb69d67b6_big64\"}}",
  "posting_rewards": 230,
  "proxied_vsf_votes": [
    0,
    0,
    0,
    0
  ],
  "proxy": "",
  "received_vesting_shares": "6876.623768 VESTS",
  "recovery_account": "steem",
  "reputation": 1977531713,
  "reset_account": "null",
  "reward_sbd_balance": "0.000 SBD",
  "reward_steem_balance": "0.000 STEEM",
  "reward_vesting_balance": "0.000000 VESTS",
  "reward_vesting_steem": "0.000 STEEM",
  "savings_balance": "0.000 STEEM",
  "savings_sbd_balance": "0.000 SBD",
  "savings_sbd_last_interest_payment": "1970-01-01T00:00:00",
  "savings_sbd_seconds": "0",
  "savings_sbd_seconds_last_update": "1970-01-01T00:00:00",
  "savings_withdraw_requests": 0,
  "sbd_balance": "0.379 SBD",
  "sbd_last_interest_payment": "2018-01-05T04:30:27",
  "sbd_seconds": "675136569",
  "sbd_seconds_last_update": "2018-02-01T00:48:45",
  "tags_usage": [],
  "to_withdraw": 0,
  "transfer_history": [],
  "vesting_balance": "0.000 STEEM",
  "vesting_shares": "1267.036038 VESTS",
  "vesting_withdraw_rate": "0.000000 VESTS",
  "vote_history": [],
  "voting_manabar": {
    "current_mana": "8143659806",
    "last_update_time": 1779085092
  },
  "voting_power": 0,
  "withdraw_routes": 0,
  "withdrawn": 0,
  "witness_votes": [],
  "witnesses_voted_for": 0,
  "rank": 508321
}

Withdraw Routes

IncomingOutgoing
Empty
Empty
{
  "incoming": [],
  "outgoing": []
}
From Date
To Date
steemdelegated 4.223 SP to @semlinker
2026/05/18 06:18:12
delegateesemlinker
delegatorsteem
vesting shares6876.623768 VESTS
Transaction InfoBlock #106150676/Trx 72d7b71141963017f0e251406f65db33a07d1662
View Raw JSON Data
{
  "block": 106150676,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "semlinker",
      "delegator": "steem",
      "vesting_shares": "6876.623768 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2026-05-18T06:18:12",
  "trx_id": "72d7b71141963017f0e251406f65db33a07d1662",
  "trx_in_block": 0,
  "virtual_op": 0
}
steemdelegated 2.557 SP to @semlinker
2026/05/13 04:26:30
delegateesemlinker
delegatorsteem
vesting shares4164.413363 VESTS
Transaction InfoBlock #106005164/Trx 75b8ec7362ea852c7cf182fab98be9b6e3982be6
View Raw JSON Data
{
  "block": 106005164,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "semlinker",
      "delegator": "steem",
      "vesting_shares": "4164.413363 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2026-05-13T04:26:30",
  "trx_id": "75b8ec7362ea852c7cf182fab98be9b6e3982be6",
  "trx_in_block": 0,
  "virtual_op": 0
}
steemdelegated 4.231 SP to @semlinker
2026/04/26 05:29:51
delegateesemlinker
delegatorsteem
vesting shares6889.139524 VESTS
Transaction InfoBlock #105518158/Trx b219866b3779687ac74b1d90e9a03033bdab3429
View Raw JSON Data
{
  "block": 105518158,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "semlinker",
      "delegator": "steem",
      "vesting_shares": "6889.139524 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2026-04-26T05:29:51",
  "trx_id": "b219866b3779687ac74b1d90e9a03033bdab3429",
  "trx_in_block": 0,
  "virtual_op": 0
}
steemdelegated 2.583 SP to @semlinker
2026/01/24 00:05:51
delegateesemlinker
delegatorsteem
vesting shares4205.960182 VESTS
Transaction InfoBlock #102871332/Trx e83691d6ef8b0c792ae84481530c81beb12cc23b
View Raw JSON Data
{
  "block": 102871332,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "semlinker",
      "delegator": "steem",
      "vesting_shares": "4205.960182 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2026-01-24T00:05:51",
  "trx_id": "e83691d6ef8b0c792ae84481530c81beb12cc23b",
  "trx_in_block": 2,
  "virtual_op": 0
}
steemdelegated 2.684 SP to @semlinker
2024/12/17 19:15:36
delegateesemlinker
delegatorsteem
vesting shares4370.179379 VESTS
Transaction InfoBlock #91317541/Trx 338a52cf207f753b124b4605b3d15dbb9a3aa0d0
View Raw JSON Data
{
  "block": 91317541,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "semlinker",
      "delegator": "steem",
      "vesting_shares": "4370.179379 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2024-12-17T19:15:36",
  "trx_id": "338a52cf207f753b124b4605b3d15dbb9a3aa0d0",
  "trx_in_block": 1,
  "virtual_op": 0
}
steemdelegated 2.788 SP to @semlinker
2023/11/14 10:56:54
delegateesemlinker
delegatorsteem
vesting shares4539.312911 VESTS
Transaction InfoBlock #79871691/Trx 243697dd12bbe6354eef518499870602d0256c73
View Raw JSON Data
{
  "block": 79871691,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "semlinker",
      "delegator": "steem",
      "vesting_shares": "4539.312911 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2023-11-14T10:56:54",
  "trx_id": "243697dd12bbe6354eef518499870602d0256c73",
  "trx_in_block": 2,
  "virtual_op": 0
}
steemdelegated 4.591 SP to @semlinker
2023/09/22 10:25:09
delegateesemlinker
delegatorsteem
vesting shares7476.221697 VESTS
Transaction InfoBlock #78362898/Trx 7486a65659a2687b39501af189d533973970be5d
View Raw JSON Data
{
  "block": 78362898,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "semlinker",
      "delegator": "steem",
      "vesting_shares": "7476.221697 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2023-09-22T10:25:09",
  "trx_id": "7486a65659a2687b39501af189d533973970be5d",
  "trx_in_block": 5,
  "virtual_op": 0
}
steemdelegated 4.727 SP to @semlinker
2022/11/03 17:52:18
delegateesemlinker
delegatorsteem
vesting shares7698.273135 VESTS
Transaction InfoBlock #69120629/Trx 82cb95af38d2b5a199652462af13c1f40e34d833
View Raw JSON Data
{
  "block": 69120629,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "semlinker",
      "delegator": "steem",
      "vesting_shares": "7698.273135 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2022-11-03T17:52:18",
  "trx_id": "82cb95af38d2b5a199652462af13c1f40e34d833",
  "trx_in_block": 0,
  "virtual_op": 0
}
steemdelegated 4.863 SP to @semlinker
2022/01/17 23:04:00
delegateesemlinker
delegatorsteem
vesting shares7918.380736 VESTS
Transaction InfoBlock #60823873/Trx fa54960005cc1be468a23e1bee43cafe5840fc8d
View Raw JSON Data
{
  "block": 60823873,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "semlinker",
      "delegator": "steem",
      "vesting_shares": "7918.380736 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2022-01-17T23:04:00",
  "trx_id": "fa54960005cc1be468a23e1bee43cafe5840fc8d",
  "trx_in_block": 2,
  "virtual_op": 0
}
steemdelegated 4.976 SP to @semlinker
2021/06/14 06:14:54
delegateesemlinker
delegatorsteem
vesting shares8102.575024 VESTS
Transaction InfoBlock #54614196/Trx e81e0bbaea3dbd8145f39ffbf8ba9d83d4e23187
View Raw JSON Data
{
  "block": 54614196,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "semlinker",
      "delegator": "steem",
      "vesting_shares": "8102.575024 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2021-06-14T06:14:54",
  "trx_id": "e81e0bbaea3dbd8145f39ffbf8ba9d83d4e23187",
  "trx_in_block": 6,
  "virtual_op": 0
}
steemdelegated 5.091 SP to @semlinker
2020/12/11 16:27:09
delegateesemlinker
delegatorsteem
vesting shares8289.996998 VESTS
Transaction InfoBlock #49361462/Trx d19979a7a8b81ce828851abecb71584d2fbf647f
View Raw JSON Data
{
  "block": 49361462,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "semlinker",
      "delegator": "steem",
      "vesting_shares": "8289.996998 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2020-12-11T16:27:09",
  "trx_id": "d19979a7a8b81ce828851abecb71584d2fbf647f",
  "trx_in_block": 0,
  "virtual_op": 0
}
steemdelegated 1.174 SP to @semlinker
2020/12/06 10:02:48
delegateesemlinker
delegatorsteem
vesting shares1912.543513 VESTS
Transaction InfoBlock #49212982/Trx 71c90c71431796e2857833263664ea87e1ef2b43
View Raw JSON Data
{
  "block": 49212982,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "semlinker",
      "delegator": "steem",
      "vesting_shares": "1912.543513 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2020-12-06T10:02:48",
  "trx_id": "71c90c71431796e2857833263664ea87e1ef2b43",
  "trx_in_block": 4,
  "virtual_op": 0
}
steemdelegated 5.095 SP to @semlinker
2020/12/05 20:04:57
delegateesemlinker
delegatorsteem
vesting shares8296.204852 VESTS
Transaction InfoBlock #49196545/Trx 26bd73ca17506ae6e66422f76983b8e48b50ed10
View Raw JSON Data
{
  "block": 49196545,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "semlinker",
      "delegator": "steem",
      "vesting_shares": "8296.204852 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2020-12-05T20:04:57",
  "trx_id": "26bd73ca17506ae6e66422f76983b8e48b50ed10",
  "trx_in_block": 3,
  "virtual_op": 0
}
steemdelegated 1.179 SP to @semlinker
2020/11/03 02:40:57
delegateesemlinker
delegatorsteem
vesting shares1920.017158 VESTS
Transaction InfoBlock #48270804/Trx 35230ecea3ea0d86abfd29b25adcdcc6718bb4e3
View Raw JSON Data
{
  "block": 48270804,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "semlinker",
      "delegator": "steem",
      "vesting_shares": "1920.017158 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2020-11-03T02:40:57",
  "trx_id": "35230ecea3ea0d86abfd29b25adcdcc6718bb4e3",
  "trx_in_block": 2,
  "virtual_op": 0
}
steemdelegated 5.219 SP to @semlinker
2020/05/09 11:05:48
delegateesemlinker
delegatorsteem
vesting shares8499.010211 VESTS
Transaction InfoBlock #43223309/Trx 94b22f3dc43b851899f75da551a5d2459a3431bf
View Raw JSON Data
{
  "block": 43223309,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "semlinker",
      "delegator": "steem",
      "vesting_shares": "8499.010211 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2020-05-09T11:05:48",
  "trx_id": "94b22f3dc43b851899f75da551a5d2459a3431bf",
  "trx_in_block": 56,
  "virtual_op": 0
}
steemdelegated 1.200 SP to @semlinker
2020/05/08 15:30:18
delegateesemlinker
delegatorsteem
vesting shares1953.311140 VESTS
Transaction InfoBlock #43200356/Trx 699f0e9d673c3d4a28eb0908196f3f9b105482cd
View Raw JSON Data
{
  "block": 43200356,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "semlinker",
      "delegator": "steem",
      "vesting_shares": "1953.311140 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2020-05-08T15:30:18",
  "trx_id": "699f0e9d673c3d4a28eb0908196f3f9b105482cd",
  "trx_in_block": 3,
  "virtual_op": 0
}
steemdelegated 5.227 SP to @semlinker
2020/04/16 03:17:00
delegateesemlinker
delegatorsteem
vesting shares8511.897659 VESTS
Transaction InfoBlock #42569140/Trx 6eb48a409884537f0a54d7c076be20fc6b0ff94b
View Raw JSON Data
{
  "block": 42569140,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "semlinker",
      "delegator": "steem",
      "vesting_shares": "8511.897659 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2020-04-16T03:17:00",
  "trx_id": "6eb48a409884537f0a54d7c076be20fc6b0ff94b",
  "trx_in_block": 12,
  "virtual_op": 0
}
2019/12/18 14:42:09
authorsteemitboard
bodyCongratulations @semlinker! You received a personal award! <table><tr><td>https://steemitimages.com/70x70/http://steemitboard.com/@semlinker/birthday2.png</td><td>Happy Birthday! - You are on the Steem blockchain for 2 years!</td></tr></table> <sub>_You can view [your badges on your Steem Board](https://steemitboard.com/@semlinker) and compare to others on the [Steem Ranking](https://steemitboard.com/ranking/index.php?name=semlinker)_</sub> ###### [Vote for @Steemitboard as a witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1) to get one more award and increased upvotes!
json metadata{"image":["https://steemitboard.com/img/notify.png"]}
parent authorsemlinker
parent permlinknaha-travel-costa-fortuna
permlinksteemitboard-notify-semlinker-20191218t144208000z
title
Transaction InfoBlock #39147468/Trx 9c4b22123a9d0d5081524cc24d90131bd27c9d65
View Raw JSON Data
{
  "block": 39147468,
  "op": [
    "comment",
    {
      "author": "steemitboard",
      "body": "Congratulations @semlinker! You received a personal award!\n\n<table><tr><td>https://steemitimages.com/70x70/http://steemitboard.com/@semlinker/birthday2.png</td><td>Happy Birthday! - You are on the Steem blockchain for 2 years!</td></tr></table>\n\n<sub>_You can view [your badges on your Steem Board](https://steemitboard.com/@semlinker) and compare to others on the [Steem Ranking](https://steemitboard.com/ranking/index.php?name=semlinker)_</sub>\n\n\n###### [Vote for @Steemitboard as a witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1) to get one more award and increased upvotes!",
      "json_metadata": "{\"image\":[\"https://steemitboard.com/img/notify.png\"]}",
      "parent_author": "semlinker",
      "parent_permlink": "naha-travel-costa-fortuna",
      "permlink": "steemitboard-notify-semlinker-20191218t144208000z",
      "title": ""
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-12-18T14:42:09",
  "trx_id": "9c4b22123a9d0d5081524cc24d90131bd27c9d65",
  "trx_in_block": 19,
  "virtual_op": 0
}
steemdelegated 5.347 SP to @semlinker
2019/05/12 20:24:06
delegateesemlinker
delegatorsteem
vesting shares8707.514472 VESTS
Transaction InfoBlock #32852083/Trx 1a39719b07a72e88452edf8c3672f2faa16bb594
View Raw JSON Data
{
  "block": 32852083,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "semlinker",
      "delegator": "steem",
      "vesting_shares": "8707.514472 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2019-05-12T20:24:06",
  "trx_id": "1a39719b07a72e88452edf8c3672f2faa16bb594",
  "trx_in_block": 4,
  "virtual_op": 0
}
2018/12/18 14:29:15
authorsteemitboard
bodyCongratulations @semlinker! You received a personal award! <table><tr><td>https://steemitimages.com/70x70/http://steemitboard.com/@semlinker/birthday1.png</td><td>1 Year on Steemit</td></tr></table> <sub>_[Click here to view your Board of Honor](https://steemitboard.com/@semlinker)_</sub> > Support [SteemitBoard's project](https://steemit.com/@steemitboard)! **[Vote for its witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1)** and **get one more award**!
json metadata{"image":["https://steemitboard.com/img/notify.png"]}
parent authorsemlinker
parent permlinknaha-travel-costa-fortuna
permlinksteemitboard-notify-semlinker-20181218t142914000z
title
Transaction InfoBlock #28673594/Trx 8c37e410990832fa4e681e4ebb1b3698025dbbea
View Raw JSON Data
{
  "block": 28673594,
  "op": [
    "comment",
    {
      "author": "steemitboard",
      "body": "Congratulations @semlinker! You received a personal award!\n\n<table><tr><td>https://steemitimages.com/70x70/http://steemitboard.com/@semlinker/birthday1.png</td><td>1 Year on Steemit</td></tr></table>\n\n<sub>_[Click here to view your Board of Honor](https://steemitboard.com/@semlinker)_</sub>\n\n\n> Support [SteemitBoard's project](https://steemit.com/@steemitboard)! **[Vote for its witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1)** and **get one more award**!",
      "json_metadata": "{\"image\":[\"https://steemitboard.com/img/notify.png\"]}",
      "parent_author": "semlinker",
      "parent_permlink": "naha-travel-costa-fortuna",
      "permlink": "steemitboard-notify-semlinker-20181218t142914000z",
      "title": ""
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-12-18T14:29:15",
  "trx_id": "8c37e410990832fa4e681e4ebb1b3698025dbbea",
  "trx_in_block": 7,
  "virtual_op": 0
}
steemdelegated 5.470 SP to @semlinker
2018/05/17 02:42:39
delegateesemlinker
delegatorsteem
vesting shares8907.029564 VESTS
Transaction InfoBlock #22497553/Trx 69b76976972a32de68fa88f3d1130da7dd2ee038
View Raw JSON Data
{
  "block": 22497553,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "semlinker",
      "delegator": "steem",
      "vesting_shares": "8907.029564 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-05-17T02:42:39",
  "trx_id": "69b76976972a32de68fa88f3d1130da7dd2ee038",
  "trx_in_block": 43,
  "virtual_op": 0
}
steemdelegated 17.995 SP to @semlinker
2018/04/16 15:55:15
delegateesemlinker
delegatorsteem
vesting shares29303.422530 VESTS
Transaction InfoBlock #21621422/Trx 058e2339f16ea3c84a38bb34132f1cd9e8e58cba
View Raw JSON Data
{
  "block": 21621422,
  "op": [
    "delegate_vesting_shares",
    {
      "delegatee": "semlinker",
      "delegator": "steem",
      "vesting_shares": "29303.422530 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-04-16T15:55:15",
  "trx_id": "058e2339f16ea3c84a38bb34132f1cd9e8e58cba",
  "trx_in_block": 5,
  "virtual_op": 0
}
2018/03/28 09:01:24
authorjimi2018
body补充分享一个以太坊DApp开发入门教程:[http://xc.hubwiz.com/course/5a952991adb3847553d205d1](http://xc.hubwiz.com/course/5a952991adb3847553d205d1?affid=20180328steemit)
json metadata{"tags":["blockchain"],"links":["http://xc.hubwiz.com/course/5a952991adb3847553d205d1?affid=20180328steemit"],"app":"steemit/0.1"}
parent authorsemlinker
parent permlink2u7csu
permlinkre-semlinker-2u7csu-20180328t090329347z
title
Transaction InfoBlock #21066046/Trx 0a0455d66779446783bda59fa89739812da4e18e
View Raw JSON Data
{
  "block": 21066046,
  "op": [
    "comment",
    {
      "author": "jimi2018",
      "body": "补充分享一个以太坊DApp开发入门教程:[http://xc.hubwiz.com/course/5a952991adb3847553d205d1](http://xc.hubwiz.com/course/5a952991adb3847553d205d1?affid=20180328steemit)",
      "json_metadata": "{\"tags\":[\"blockchain\"],\"links\":[\"http://xc.hubwiz.com/course/5a952991adb3847553d205d1?affid=20180328steemit\"],\"app\":\"steemit/0.1\"}",
      "parent_author": "semlinker",
      "parent_permlink": "2u7csu",
      "permlink": "re-semlinker-2u7csu-20180328t090329347z",
      "title": ""
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-03-28T09:01:24",
  "trx_id": "0a0455d66779446783bda59fa89739812da4e18e",
  "trx_in_block": 16,
  "virtual_op": 0
}
2018/02/26 10:25:36
authorsemlinker
permlinknaha-travel-costa-fortuna
voterdtubix
weight5000 (50.00%)
Transaction InfoBlock #20205314/Trx 9474cb81a33058c89ac3cdd7f9b9f9dd075baa51
View Raw JSON Data
{
  "block": 20205314,
  "op": [
    "vote",
    {
      "author": "semlinker",
      "permlink": "naha-travel-costa-fortuna",
      "voter": "dtubix",
      "weight": 5000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-02-26T10:25:36",
  "trx_id": "9474cb81a33058c89ac3cdd7f9b9f9dd075baa51",
  "trx_in_block": 36,
  "virtual_op": 0
}
semlinkerclaimed reward balance: 0.048 SBD, 0.011 SP
2018/02/01 00:48:45
accountsemlinker
reward sbd0.048 SBD
reward steem0.000 STEEM
reward vests18.418537 VESTS
Transaction InfoBlock #19474561/Trx 1b6cbc1253fb1b04c1d5024566c9c1c90a1f87c4
View Raw JSON Data
{
  "block": 19474561,
  "op": [
    "claim_reward_balance",
    {
      "account": "semlinker",
      "reward_sbd": "0.048 SBD",
      "reward_steem": "0.000 STEEM",
      "reward_vests": "18.418537 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-02-01T00:48:45",
  "trx_id": "1b6cbc1253fb1b04c1d5024566c9c1c90a1f87c4",
  "trx_in_block": 25,
  "virtual_op": 0
}
2018/01/28 15:21:48
authorphotocontests
body<b>World of Photography Beta V1.0</b><br><a href="https://steemit.com/introduceyourself/@photocontests/readme">>Learn more here<</a><br><br> Thank you for participating in #colourfulphotography, the weekly selection will be released on <b>Friday</b>.<br><br> You have earned <b>5.05 XP</b> for sharing your photo! <br><table><tr><td><b>Daily Stats</b><br>Daily photos: 1/2 <br> Daily comments: 0/5<br>Multiplier: 1.01<br><sub>Server time: 16:21:45</sub></td><td><b>Account Level: 0</b><br>Total XP: 5.05/100.00<br>Total Photos: 1<br>Total comments: 0<br> Total contest wins: 0</td></tr></table>When you reach level 1 you will start receiving up to two daily upvotes<br><br> <b>Follow:</b> @photocontests<br><b>Join the Discord channel:</b> <a href="https://discord.gg/2pmd5Dr">click!</a><br><b>Play and win SBD: </b>@fairlotto<br><b>Learn how to program Steem-Python applications: </b>@steempytutorials<br><b>Developed and sponsored by:</b> @juliank
json metadata
parent authorsemlinker
parent permlinknaha-travel-costa-fortuna
permlinkre-naha-travel-costa-fortuna-20180128t152145
title
Transaction InfoBlock #19376900/Trx 5666aa1f0fce1504cd8c79d3d7bef782f15be980
View Raw JSON Data
{
  "block": 19376900,
  "op": [
    "comment",
    {
      "author": "photocontests",
      "body": "<b>World of Photography Beta V1.0</b><br><a href=\"https://steemit.com/introduceyourself/@photocontests/readme\">>Learn more here<</a><br><br> Thank you for participating in #colourfulphotography, the weekly selection will be released on <b>Friday</b>.<br><br> You have earned <b>5.05 XP</b> for sharing your photo! <br><table><tr><td><b>Daily Stats</b><br>Daily photos: 1/2 <br> Daily comments: 0/5<br>Multiplier: 1.01<br><sub>Server time: 16:21:45</sub></td><td><b>Account Level: 0</b><br>Total XP: 5.05/100.00<br>Total Photos: 1<br>Total comments: 0<br> Total contest wins: 0</td></tr></table>When you reach level 1 you will start receiving up to two daily upvotes<br><br> <b>Follow:</b> @photocontests<br><b>Join the Discord channel:</b> <a href=\"https://discord.gg/2pmd5Dr\">click!</a><br><b>Play and win SBD: </b>@fairlotto<br><b>Learn how to program Steem-Python applications: </b>@steempytutorials<br><b>Developed and sponsored by:</b> @juliank",
      "json_metadata": "",
      "parent_author": "semlinker",
      "parent_permlink": "naha-travel-costa-fortuna",
      "permlink": "re-naha-travel-costa-fortuna-20180128t152145",
      "title": ""
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-28T15:21:48",
  "trx_id": "5666aa1f0fce1504cd8c79d3d7bef782f15be980",
  "trx_in_block": 24,
  "virtual_op": 0
}
2018/01/28 15:01:30
authorsemlinker
bodyWonderful journey with Costa Fortuna ![costa-fortuna.jpeg](https://steemitimages.com/DQmWk2S61EGGrdip4PXHpDT29kvSxUmvRRKNHv6ZRgAvhtn/costa-fortuna.jpeg)
json metadata{"tags":["colourfulphotography","photograph","travel"],"image":["https://steemitimages.com/DQmWk2S61EGGrdip4PXHpDT29kvSxUmvRRKNHv6ZRgAvhtn/costa-fortuna.jpeg"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkcolourfulphotography
permlinknaha-travel-costa-fortuna
titleNaha Travel - Costa Fortuna
Transaction InfoBlock #19376495/Trx 17afb205f3a5d1aa6a543fc6ca72bfeae83b93af
View Raw JSON Data
{
  "block": 19376495,
  "op": [
    "comment",
    {
      "author": "semlinker",
      "body": "Wonderful journey with Costa Fortuna\n![costa-fortuna.jpeg](https://steemitimages.com/DQmWk2S61EGGrdip4PXHpDT29kvSxUmvRRKNHv6ZRgAvhtn/costa-fortuna.jpeg)",
      "json_metadata": "{\"tags\":[\"colourfulphotography\",\"photograph\",\"travel\"],\"image\":[\"https://steemitimages.com/DQmWk2S61EGGrdip4PXHpDT29kvSxUmvRRKNHv6ZRgAvhtn/costa-fortuna.jpeg\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "colourfulphotography",
      "permlink": "naha-travel-costa-fortuna",
      "title": "Naha Travel - Costa Fortuna"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-28T15:01:30",
  "trx_id": "17afb205f3a5d1aa6a543fc6ca72bfeae83b93af",
  "trx_in_block": 37,
  "virtual_op": 0
}
2018/01/28 14:55:09
authorleftbank
permlinksunset-in-maui
votersemlinker
weight10000 (100.00%)
Transaction InfoBlock #19376368/Trx 4307b4e7988d7f39da1bdb17d2f353c8cb371db0
View Raw JSON Data
{
  "block": 19376368,
  "op": [
    "vote",
    {
      "author": "leftbank",
      "permlink": "sunset-in-maui",
      "voter": "semlinker",
      "weight": 10000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-28T14:55:09",
  "trx_id": "4307b4e7988d7f39da1bdb17d2f353c8cb371db0",
  "trx_in_block": 49,
  "virtual_op": 0
}
2018/01/28 14:13:27
authorreko
permlinksteemfollower-manual-curation-platform-new-project-steemclient
votersemlinker
weight10000 (100.00%)
Transaction InfoBlock #19375534/Trx cab8ad6377bbab8b40a0d42820e9958f9ce69889
View Raw JSON Data
{
  "block": 19375534,
  "op": [
    "vote",
    {
      "author": "reko",
      "permlink": "steemfollower-manual-curation-platform-new-project-steemclient",
      "voter": "semlinker",
      "weight": 10000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-28T14:13:27",
  "trx_id": "cab8ad6377bbab8b40a0d42820e9958f9ce69889",
  "trx_in_block": 41,
  "virtual_op": 0
}
semlinkerpublished a new post: pwa-push-api
2018/01/28 14:10:45
authorsemlinker
bodyPush API 允许 Web 应用程序拥有接收服务器推送消息的能力。对于 Web 应用来说,要能够接收到推送的消息,需要有一个被激活的 service worker。当 service worker 处于激活状态时,我们可以使用 PushManager 实例的 subscribe 方法来订阅推送通知。 [Push API](https://developer.mozilla.org/en-US/docs/Web/API/Push_API) 的 PushManager 接口提供了从第三方服务器接收通知以及请求推送通知 URL 的方法,通过 ServiceWorkerRegistration 对象的 pushManager 属性可以轻松地访问到 PushManager 实例。那么如何获取 ServiceWorkerRegistration 对象呢?这个嘛,先看一下以下代码,估计你就懂了: ```javascript navigator.serviceWorker.register('service-worker.js') .then((registration) => { console.log(registration); }, (err) => { console.log(err); }); ``` 以上代码运行后,控制台输出的结果如下图所示: ![sw-push-manager.png](https://steemitimages.com/DQmc1BmujQWsNbNuisttJ2zFKgB37aRSpacjF3HZu6iwYSo/sw-push-manager.png) 现在我们已经知道如何访问 PushManager 实例,目前该实例有以下三个方法: - getSubscription():该方法返回一个 Promise 对象,若已订阅则返回一个包含现有订阅详细信息的 PushSubscription 对象,若未订阅则返回 null; - permissionState():该方法返回一个 Promise 对象,用于获取当前 PushManager 对象的权限状态,可能的值为 `'granted'`、`'denied'` 或 `'prompt'`; - subscribe():该方法返回一个 Promise 对象,用于订阅推送服务。若订阅成功,则返回一个包含现有订阅详细信息的 PushSubscription 对象。 了解完上面的知识,我们来看一下简单的示例: - subscribe(): ```javascript navigator.serviceWorker .register('service-worker.js') .then((registration) => { // 获取pushManager实例,执行订阅操作 registration.pushManager.subscribe() .then((pushSubscription) => { console.log(pushSubscription); },(error) => { console.log(error); }); }, (err) => { console.log(err); }); ``` - getSubscription(): ```javascript registration.pushManager .getSubscription() .then(function (subscription) { // 若尚未订阅则subscription的值为null isSubscribed = !(subscription === null); if (isSubscribed) { console.log('用户已订阅'); } else { console.log('用户未订阅'); } }); ``` ### Service Worker Push Event 在前面的文章中,我们已经介绍过了如何注册 service worker,接下来我们来简单介绍 service worker 如何接收服务端发送的通知消息。Push API 中定义了 push 事件,通过 push 事件我们就能够接收推送服务器发送的消息,具体示例如下: ```javascript self.addEventListener('push', function(event) { if(event.data) { // 假设发送的数据格式为JSON字符串 var obj = event.data.json(); console.log(obj); } }); ``` 不知道小伙伴是否还记得 [PWA 学习笔记之 Web Notifications API](https://steemit.com/cn-programming/@semlinker/pwa-web-notifications-api) 这篇文章中介绍的知识,一般情况下当收到推送通知的时候,我们会立即向用户显示通知消息。在 service worker 工作环境中,我们也可以通过 `self.registration` 对象的 showNotification 方法,来显示通知消息。 接下来我们来更新一下上面的代码,来实现通知消息的显示,具体代码如下(service-worker.js): ```javascript self.addEventListener('push', function (event) { if (!(self.Notification && self.Notification.permission === 'granted')) { return; } var data = {}; if (event.data) { data = event.data.json(); } // 解析通知内容 var title = data.title || "Introducing WhatFontIs is the Easiest Way to Identify Fonts Online"; var message = data.message || "A free service to help you ..."; var icon = "https://dab1nmslvvntp.cloudfront.net/wp-content/uploads/2017/10/[email protected]"; var notification = self.registration.showNotification(title, { body: message, icon: icon }); }); // 处理通知消息的点击事件 self.onnotificationclick = function () { if (clients.openWindow) { clients.openWindow('https://www.sitepoint.com/finding-fonts-whatfontis/'); } }; ``` 代码已经更新完了,那么我们应该如何验证上面的功能代码呢?Chrome 的开发大神们还是很给力的,已经考虑到这个需求,早就为我们内置了测试工具。该工具藏在哪里呢?哈哈,估计一些小伙伴早就与它 “邂逅” 了。Are you ready,Follow Me: - 首先打开 Chrome 开发者工具 - 然后选择 Application Tab 页 - 接着选择左侧 Service Workers 菜单 - 最后目光聚焦到 Push 标签后的输入框与 Push 按钮 工具找到了,我们立马来实战一下,因为我们预期的数据格式是 JSON,所以我们在 Push 标签后的输入框,输入以下内容: ```json {"title": "Greeting", "message": "Hello Semlinker"} ``` 输入完成后,点击输入框右侧的 Push 按钮,不出意外的话,你将看到以下通知,具体如下图所示: ![push-event-local.jpg](https://steemitimages.com/DQmeVymScoo3uw1gGaWXkEFViromt4QWDyJ8ZAV7ZuQJsCH/push-event-local.jpg) 虽然 Push Event 本地已经验证通过了,但实际工作中,我们需求从推送服务器接收通知消息。在介绍如何利用推送服务器发送消息通知前,我们先来了解一下 Webpush 架构: ### Webpush Architecture ``` +-------+ +--------------+ +-------------+ | UA | | Push Service | | Application | +-------+ +--------------+ | Server | | | +-------------+ | Subscribe | | |--------------------->| | | Monitor | | |<====================>| | | | | | Distribute Push Resource | |-------------------------------------------->| | | | : : : | | Push Message | | Push Message |<---------------------| |<---------------------| | | | | ``` (图形来源:https://tools.ietf.org/html/draft-ietf-webpush-protocol-12) 结合上面的架构图,我们来分析一下主要的消息推送流程: - 首先 UA (User-Agent)用户代理,订阅推送服务(Push Service); - 当应用服务器产生新的消息时,会把新的消息发送至推送服务器; - 推送服务器会根据消息类型,匹配对应的订阅者列表,然后把接收到的新消息推送至每个订阅者(UA)。 是不是感觉看起来挺简单的,实际上真实的开发流程会相对复杂,在实战 Webpush 前,我们先来梳理一下相应的开发流程: - 判断当前平台是否支持 Service Worker 和 PushManager,若支持则调用 service worker 对象的 register 方法,注册 service worker; - Service Worker 注册成功后,保存 ServiceWorkerRegistration 对象的引用,同时通过该引用对象的pushManager 属性,访问 PushManager 对象,然后利用 PushManager 对象提供的 getSubscription 方法判断当前的订阅状态,若未订阅,则调用 PushManager 对象的 subscribe 方法执行订阅操作; - PushManager 对象的 subscribe 方法的参数对象,支持两个属性: - `userVisibleOnly`: 布尔值,表示返回的推送订阅将只能被用于对用户可见的消息。 - applicationServerKey:推送服务器用来向客户端应用发送消息的公钥。该值是应用程序服务器生成的签名密钥对的一部分,可使用在 P-256 曲线上实现的椭圆曲线数字签名(ECDSA)。可以是[`DOMString`](https://developer.mozilla.org/zh-CN/docs/Web/API/DOMString) 或 [`ArrayBuffer`](https://developer.mozilla.org/zh-CN/docs/Web/API/ArrayBuffer)。 - 订阅成功后,当 Push Service 接收到新消息时,会根据存储的 endpoint (端点)把新的消息推送到订阅目标。 了解完开发流程,我们开始来实战 Webpush。这里我们的 Push Service 直接使用 [web-push-codelab](https://web-push-codelab.glitch.me/) 提供的服务。首先进入 [web-push-codelab](https://web-push-codelab.glitch.me/) 页面,复制 Application Server Keys 区域中的 **Public Key**,该 Key 用于生成执行 subscribe 操作时,所需的 applicationServerKey 参数。 main.js 文件的代码如下: ```javascript var swRegistration, isSubscribed; // 保存 https://web-push-codelab.glitch.me/ 页面中的Public Key,用于生成applicationServerKey const applicationServerPublicKey = 'BCR82cPVPlEexaFKlozZq-3K7p8ey8WBobzLhfNnsC3IB0yXtof2mzW7n4300SHMeWYSFtSZwtR53HlVCKV25Ow'; // 生成PushManager订阅时所需的applicationServerKey参数值 const applicationServerKey = urlBase64ToUint8Array(applicationServerPublicKey); // 判断是否支持Service Worker 和 PushManager if ('serviceWorker' in navigator && 'PushManager' in window) { console.log('Service Worker and Push is supported'); navigator.serviceWorker.register('service-worker.js') .then(function (swReg) { console.log('Service Worker is registered', swReg); swRegistration = swReg; checkSubscribed(); }) .catch(function (error) { console.error('Service Worker Error', error); }); } else { console.warn('Push messaging is not supported'); } /** * 判断PushManager的订阅状态,若未订阅则执行订阅操作 */ function checkSubscribed() { if (swRegistration) { swRegistration.pushManager.getSubscription() .then(function (subscription) { isSubscribed = !(subscription === null); if (isSubscribed) { console.log('User IS subscribed.'); } else { console.log('User is NOT subscribed.'); subscribe(); } }); } } /** * 执行订阅操作 */ function subscribe() { swRegistration.pushManager .subscribe({ userVisibleOnly: true, applicationServerKey: applicationServerKey }).then(function (subscription) { console.log('User is subscribed:', subscription); console.log(JSON.stringify(subscription)); isSubscribed = true; }) .catch(function (err) { console.log('Failed to subscribe the user: ', err); }); } /** * Base64转化为Uint8Array * @param base64String * @returns {Uint8Array} */ function urlBase64ToUint8Array(base64String) { const padding = '='.repeat((4 - base64String.length % 4) % 4); const base64 = (base64String + padding) .replace(/\-/g, '+') .replace(/_/g, '/'); const rawData = window.atob(base64); const outputArray = new Uint8Array(rawData.length); for (let i = 0; i < rawData.length; ++i) { outputArray[i] = rawData.charCodeAt(i); } return outputArray; } ``` service-worker.js 文件的代码如下: ```javascript self.addEventListener('push', function (event) { if (!(self.Notification && self.Notification.permission === 'granted')) { return; } var data = {}; if (event.data) { data = event.data.json(); } // 解析通知内容 var title = data.title || "Introducing WhatFontIs is the Easiest Way to Identify Fonts Online"; var message = data.message || "A free service to help you ..."; var icon = "https://dab1nmslvvntp.cloudfront.net/wp-content/uploads/2017/10/[email protected]"; var notification = self.registration.showNotification(title, { body: message, icon: icon }); }); // 处理通知消息的点击事件 self.onnotificationclick = function () { if (clients.openWindow) { clients.openWindow('https://www.sitepoint.com/finding-fonts-whatfontis/'); } }; ``` 以上代码成功运行后,我们需要把 PushManager 订阅成功后返回的 subscription 对象,执行序列化操作,然后把输出的结果复制到 [web-push-codelab](https://web-push-codelab.glitch.me/) 页面上 **Subscription to Send To** 对应的 textarea 输入框中(可以在开发者工具的控制台中复制对应的订阅信息),复制完订阅信息后,我们就可以来测试一下远程的消息推送了,在 [web-push-codelab](https://web-push-codelab.glitch.me/) 页面上 **Text to Send** 对应的 textarea 输入框输入以下测试数据: ```json {"title": "Greeting - Remote", "message": "Hello Semlinker - Remote"} ``` 最后点击 [web-push-codelab](https://web-push-codelab.glitch.me/) 页面上的 **SEND PUSH MESSAGE** 按钮发送推送消息,不出意外的话,你将看到以下通知,具体如下图所示: ![push-event-remote.jpg](https://steemitimages.com/DQmRpqcbjvxNzk5ayu5AbqLEbMMNrWWsk1gn68n3PT1FnCM/push-event-remote.jpg) 本文利用两个示例,简单介绍了 Push API 的相关知识,实际上 Web Push 还会涉及其它的知识,还有挺多值得我们深入研究的。有兴趣的小伙伴可以参考 [MDN - Using the Push API](https://developer.mozilla.org/zh-CN/docs/Web/API/Push_API/Using_the_Push_API) 和 [向网络应用添加推送通知](https://developers.google.com/web/fundamentals/codelabs/push-notifications/?hl=zh-cn) 这两篇文章。刚开始学习PWA,以上内容有误之处,请小伙伴们多多指教。 ### 参考资源 - [MDN - Using the Push API](https://developer.mozilla.org/zh-CN/docs/Web/API/Push_API/Using_the_Push_API) - [向网络应用添加推送通知](https://developers.google.com/web/fundamentals/codelabs/push-notifications/?hl=zh-cn)
json metadata{"tags":["cn-programming","pwa","cn"],"image":["https://steemitimages.com/DQmc1BmujQWsNbNuisttJ2zFKgB37aRSpacjF3HZu6iwYSo/sw-push-manager.png","https://steemitimages.com/DQmeVymScoo3uw1gGaWXkEFViromt4QWDyJ8ZAV7ZuQJsCH/push-event-local.jpg","https://steemitimages.com/DQmRpqcbjvxNzk5ayu5AbqLEbMMNrWWsk1gn68n3PT1FnCM/push-event-remote.jpg"],"links":["https://developer.mozilla.org/en-US/docs/Web/API/Push_API","https://steemit.com/cn-programming/@semlinker/pwa-web-notifications-api","https://tools.ietf.org/html/draft-ietf-webpush-protocol-12)","https://developer.mozilla.org/zh-CN/docs/Web/API/DOMString","https://developer.mozilla.org/zh-CN/docs/Web/API/ArrayBuffer","https://web-push-codelab.glitch.me/","https://developer.mozilla.org/zh-CN/docs/Web/API/Push_API/Using_the_Push_API","https://developers.google.com/web/fundamentals/codelabs/push-notifications/?hl=zh-cn"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkcn-programming
permlinkpwa-push-api
titlePWA 学习笔记之 Push API
Transaction InfoBlock #19375480/Trx 5ca0e8a903cc1554bc425d6d22a25bc57716b1db
View Raw JSON Data
{
  "block": 19375480,
  "op": [
    "comment",
    {
      "author": "semlinker",
      "body": "Push API 允许 Web 应用程序拥有接收服务器推送消息的能力。对于 Web 应用来说,要能够接收到推送的消息,需要有一个被激活的 service worker。当 service worker 处于激活状态时,我们可以使用 PushManager 实例的 subscribe 方法来订阅推送通知。\n [Push API](https://developer.mozilla.org/en-US/docs/Web/API/Push_API) 的 PushManager 接口提供了从第三方服务器接收通知以及请求推送通知 URL 的方法,通过  ServiceWorkerRegistration 对象的 pushManager 属性可以轻松地访问到 PushManager 实例。那么如何获取 ServiceWorkerRegistration 对象呢?这个嘛,先看一下以下代码,估计你就懂了:\n\n```javascript\nnavigator.serviceWorker.register('service-worker.js')\n.then((registration) => {\n  console.log(registration);\n}, (err) => {\n  console.log(err);\n});\n```\n\n以上代码运行后,控制台输出的结果如下图所示:\n\n![sw-push-manager.png](https://steemitimages.com/DQmc1BmujQWsNbNuisttJ2zFKgB37aRSpacjF3HZu6iwYSo/sw-push-manager.png)\n\n现在我们已经知道如何访问 PushManager 实例,目前该实例有以下三个方法:\n\n- getSubscription():该方法返回一个 Promise 对象,若已订阅则返回一个包含现有订阅详细信息的 PushSubscription 对象,若未订阅则返回 null;\n- permissionState():该方法返回一个 Promise 对象,用于获取当前 PushManager 对象的权限状态,可能的值为 `'granted'`、`'denied'` 或  `'prompt'`;\n- subscribe():该方法返回一个 Promise 对象,用于订阅推送服务。若订阅成功,则返回一个包含现有订阅详细信息的 PushSubscription 对象。\n\n了解完上面的知识,我们来看一下简单的示例:\n\n- subscribe():\n\n```javascript\nnavigator.serviceWorker\n  .register('service-worker.js')\n  .then((registration) => {\n   // 获取pushManager实例,执行订阅操作\n   registration.pushManager.subscribe()\n     .then((pushSubscription) => {\n        console.log(pushSubscription);\n     },(error) => {\n        console.log(error);\n     });\n   }, (err) => {\n       console.log(err);\n});\n```\n\n- getSubscription():\n\n```javascript\nregistration.pushManager\n  .getSubscription()\n  .then(function (subscription) {\n      // 若尚未订阅则subscription的值为null\n     isSubscribed = !(subscription === null);\n     if (isSubscribed) {\n       console.log('用户已订阅');\n     } else {\n       console.log('用户未订阅');\n     }\n});\n```\n\n### Service Worker Push Event\n\n在前面的文章中,我们已经介绍过了如何注册 service worker,接下来我们来简单介绍 service worker 如何接收服务端发送的通知消息。Push API 中定义了 push 事件,通过 push 事件我们就能够接收推送服务器发送的消息,具体示例如下:\n\n```javascript\nself.addEventListener('push', function(event) {\n  if(event.data) {\n    // 假设发送的数据格式为JSON字符串\n    var obj = event.data.json();\n    console.log(obj);\n  }\n});\n```\n\n不知道小伙伴是否还记得 [PWA 学习笔记之 Web Notifications API](https://steemit.com/cn-programming/@semlinker/pwa-web-notifications-api) 这篇文章中介绍的知识,一般情况下当收到推送通知的时候,我们会立即向用户显示通知消息。在 service worker 工作环境中,我们也可以通过 `self.registration` 对象的 showNotification 方法,来显示通知消息。\n\n接下来我们来更新一下上面的代码,来实现通知消息的显示,具体代码如下(service-worker.js):\n\n```javascript\nself.addEventListener('push', function (event) {\n    if (!(self.Notification && self.Notification.permission === 'granted')) {\n        return;\n    }\n    var data = {};\n    if (event.data) {\n        data = event.data.json();\n    }\n    // 解析通知内容\n    var title = data.title || \"Introducing WhatFontIs is the Easiest Way to Identify Fonts Online\";\n    var message = data.message || \"A free service to help you ...\";\n    var icon = \"https://dab1nmslvvntp.cloudfront.net/wp-content/uploads/2017/10/[email protected]\";\n    var notification = self.registration.showNotification(title, {\n        body: message,\n        icon: icon\n    });\n});\n\n// 处理通知消息的点击事件\nself.onnotificationclick = function () {\n    if (clients.openWindow) {\n        clients.openWindow('https://www.sitepoint.com/finding-fonts-whatfontis/');\n    }\n};\n```\n\n代码已经更新完了,那么我们应该如何验证上面的功能代码呢?Chrome 的开发大神们还是很给力的,已经考虑到这个需求,早就为我们内置了测试工具。该工具藏在哪里呢?哈哈,估计一些小伙伴早就与它 “邂逅” 了。Are you ready,Follow Me:\n\n- 首先打开 Chrome 开发者工具\n- 然后选择 Application Tab 页\n- 接着选择左侧 Service Workers 菜单\n- 最后目光聚焦到 Push 标签后的输入框与 Push 按钮 \n\n工具找到了,我们立马来实战一下,因为我们预期的数据格式是 JSON,所以我们在 Push 标签后的输入框,输入以下内容:\n\n```json\n{\"title\": \"Greeting\", \"message\": \"Hello Semlinker\"}\n```\n\n输入完成后,点击输入框右侧的 Push 按钮,不出意外的话,你将看到以下通知,具体如下图所示:\n\n![push-event-local.jpg](https://steemitimages.com/DQmeVymScoo3uw1gGaWXkEFViromt4QWDyJ8ZAV7ZuQJsCH/push-event-local.jpg)\n\n虽然 Push Event 本地已经验证通过了,但实际工作中,我们需求从推送服务器接收通知消息。在介绍如何利用推送服务器发送消息通知前,我们先来了解一下 Webpush 架构:\n\n### Webpush Architecture\n\n```\n    +-------+           +--------------+       +-------------+\n    |  UA   |           | Push Service |       | Application |\n    +-------+           +--------------+       |   Server    |\n        |                      |               +-------------+\n        |      Subscribe       |                      |\n        |--------------------->|                      |\n        |       Monitor        |                      |\n        |<====================>|                      |\n        |                      |                      |\n        |          Distribute Push Resource           |\n        |-------------------------------------------->|\n        |                      |                      |\n        :                      :                      :\n        |                      |     Push Message     |\n        |    Push Message      |<---------------------|\n        |<---------------------|                      |\n        |                      |                      |\n\n```\n\n(图形来源:https://tools.ietf.org/html/draft-ietf-webpush-protocol-12)\n\n结合上面的架构图,我们来分析一下主要的消息推送流程:\n\n- 首先 UA (User-Agent)用户代理,订阅推送服务(Push Service);\n- 当应用服务器产生新的消息时,会把新的消息发送至推送服务器;\n- 推送服务器会根据消息类型,匹配对应的订阅者列表,然后把接收到的新消息推送至每个订阅者(UA)。\n\n是不是感觉看起来挺简单的,实际上真实的开发流程会相对复杂,在实战 Webpush 前,我们先来梳理一下相应的开发流程:\n\n- 判断当前平台是否支持 Service Worker 和 PushManager,若支持则调用 service worker 对象的 register 方法,注册 service worker;\n- Service Worker 注册成功后,保存 ServiceWorkerRegistration  对象的引用,同时通过该引用对象的pushManager 属性,访问 PushManager 对象,然后利用 PushManager 对象提供的 getSubscription 方法判断当前的订阅状态,若未订阅,则调用 PushManager 对象的 subscribe 方法执行订阅操作;\n- PushManager 对象的 subscribe 方法的参数对象,支持两个属性:\n  - `userVisibleOnly`: 布尔值,表示返回的推送订阅将只能被用于对用户可见的消息。\n  - applicationServerKey:推送服务器用来向客户端应用发送消息的公钥。该值是应用程序服务器生成的签名密钥对的一部分,可使用在 P-256 曲线上实现的椭圆曲线数字签名(ECDSA)。可以是[`DOMString`](https://developer.mozilla.org/zh-CN/docs/Web/API/DOMString) 或 [`ArrayBuffer`](https://developer.mozilla.org/zh-CN/docs/Web/API/ArrayBuffer)。\n- 订阅成功后,当 Push Service 接收到新消息时,会根据存储的 endpoint (端点)把新的消息推送到订阅目标。\n\n了解完开发流程,我们开始来实战 Webpush。这里我们的 Push Service 直接使用 [web-push-codelab](https://web-push-codelab.glitch.me/) 提供的服务。首先进入 [web-push-codelab](https://web-push-codelab.glitch.me/) 页面,复制 Application Server Keys 区域中的 **Public Key**,该 Key 用于生成执行 subscribe 操作时,所需的 applicationServerKey 参数。\n\nmain.js 文件的代码如下:\n\n```javascript\nvar swRegistration, isSubscribed;\n// 保存 https://web-push-codelab.glitch.me/ 页面中的Public Key,用于生成applicationServerKey\nconst applicationServerPublicKey = 'BCR82cPVPlEexaFKlozZq-3K7p8ey8WBobzLhfNnsC3IB0yXtof2mzW7n4300SHMeWYSFtSZwtR53HlVCKV25Ow';\n// 生成PushManager订阅时所需的applicationServerKey参数值\nconst applicationServerKey = urlBase64ToUint8Array(applicationServerPublicKey);\n\n// 判断是否支持Service Worker 和 PushManager\nif ('serviceWorker' in navigator && 'PushManager' in window) {\n    console.log('Service Worker and Push is supported');\n    navigator.serviceWorker.register('service-worker.js')\n        .then(function (swReg) {\n            console.log('Service Worker is registered', swReg);\n            swRegistration = swReg;\n            checkSubscribed();\n        })\n        .catch(function (error) {\n            console.error('Service Worker Error', error);\n        });\n} else {\n    console.warn('Push messaging is not supported');\n}\n\n/**\n * 判断PushManager的订阅状态,若未订阅则执行订阅操作\n */\nfunction checkSubscribed() {\n    if (swRegistration) {\n        swRegistration.pushManager.getSubscription()\n            .then(function (subscription) {\n                isSubscribed = !(subscription === null);\n                if (isSubscribed) {\n                    console.log('User IS subscribed.');\n                } else {\n                    console.log('User is NOT subscribed.');\n                    subscribe();\n                }\n            });\n    }\n}\n\n/**\n * 执行订阅操作\n */\nfunction subscribe() {\n    swRegistration.pushManager\n        .subscribe({\n            userVisibleOnly: true,\n            applicationServerKey: applicationServerKey\n        }).then(function (subscription) {\n            console.log('User is subscribed:', subscription);\n            console.log(JSON.stringify(subscription));\n            isSubscribed = true;\n        })\n        .catch(function (err) {\n            console.log('Failed to subscribe the user: ', err);\n        });\n}\n\n/**\n * Base64转化为Uint8Array\n * @param base64String\n * @returns {Uint8Array}\n */\nfunction urlBase64ToUint8Array(base64String) {\n    const padding = '='.repeat((4 - base64String.length % 4) % 4);\n    const base64 = (base64String + padding)\n        .replace(/\\-/g, '+')\n        .replace(/_/g, '/');\n\n    const rawData = window.atob(base64);\n    const outputArray = new Uint8Array(rawData.length);\n\n    for (let i = 0; i < rawData.length; ++i) {\n        outputArray[i] = rawData.charCodeAt(i);\n    }\n    return outputArray;\n}\n```\n\nservice-worker.js 文件的代码如下:\n\n```javascript\nself.addEventListener('push', function (event) {\n    if (!(self.Notification && self.Notification.permission === 'granted')) {\n        return;\n    }\n    var data = {};\n    if (event.data) {\n        data = event.data.json();\n    }\n    // 解析通知内容\n    var title = data.title || \"Introducing WhatFontIs is the Easiest Way to Identify Fonts Online\";\n    var message = data.message || \"A free service to help you ...\";\n    var icon = \"https://dab1nmslvvntp.cloudfront.net/wp-content/uploads/2017/10/[email protected]\";\n    var notification = self.registration.showNotification(title, {\n        body: message,\n        icon: icon\n    });\n});\n\n// 处理通知消息的点击事件\nself.onnotificationclick = function () {\n    if (clients.openWindow) {\n        clients.openWindow('https://www.sitepoint.com/finding-fonts-whatfontis/');\n    }\n};\n```\n\n以上代码成功运行后,我们需要把 PushManager 订阅成功后返回的 subscription 对象,执行序列化操作,然后把输出的结果复制到 [web-push-codelab](https://web-push-codelab.glitch.me/) 页面上 **Subscription to Send To** 对应的 textarea 输入框中(可以在开发者工具的控制台中复制对应的订阅信息),复制完订阅信息后,我们就可以来测试一下远程的消息推送了,在 [web-push-codelab](https://web-push-codelab.glitch.me/) 页面上  **Text to Send** 对应的 textarea 输入框输入以下测试数据:\n\n```json\n{\"title\": \"Greeting - Remote\", \"message\": \"Hello Semlinker - Remote\"}\n```\n\n最后点击 [web-push-codelab](https://web-push-codelab.glitch.me/) 页面上的 **SEND PUSH MESSAGE** 按钮发送推送消息,不出意外的话,你将看到以下通知,具体如下图所示:\n\n![push-event-remote.jpg](https://steemitimages.com/DQmRpqcbjvxNzk5ayu5AbqLEbMMNrWWsk1gn68n3PT1FnCM/push-event-remote.jpg)\n\n本文利用两个示例,简单介绍了 Push API 的相关知识,实际上 Web Push 还会涉及其它的知识,还有挺多值得我们深入研究的。有兴趣的小伙伴可以参考 [MDN - Using the Push API](https://developer.mozilla.org/zh-CN/docs/Web/API/Push_API/Using_the_Push_API) 和 [向网络应用添加推送通知](https://developers.google.com/web/fundamentals/codelabs/push-notifications/?hl=zh-cn) 这两篇文章。刚开始学习PWA,以上内容有误之处,请小伙伴们多多指教。\n\n### 参考资源\n\n-  [MDN - Using the Push API](https://developer.mozilla.org/zh-CN/docs/Web/API/Push_API/Using_the_Push_API)\n- [向网络应用添加推送通知](https://developers.google.com/web/fundamentals/codelabs/push-notifications/?hl=zh-cn)",
      "json_metadata": "{\"tags\":[\"cn-programming\",\"pwa\",\"cn\"],\"image\":[\"https://steemitimages.com/DQmc1BmujQWsNbNuisttJ2zFKgB37aRSpacjF3HZu6iwYSo/sw-push-manager.png\",\"https://steemitimages.com/DQmeVymScoo3uw1gGaWXkEFViromt4QWDyJ8ZAV7ZuQJsCH/push-event-local.jpg\",\"https://steemitimages.com/DQmRpqcbjvxNzk5ayu5AbqLEbMMNrWWsk1gn68n3PT1FnCM/push-event-remote.jpg\"],\"links\":[\"https://developer.mozilla.org/en-US/docs/Web/API/Push_API\",\"https://steemit.com/cn-programming/@semlinker/pwa-web-notifications-api\",\"https://tools.ietf.org/html/draft-ietf-webpush-protocol-12)\",\"https://developer.mozilla.org/zh-CN/docs/Web/API/DOMString\",\"https://developer.mozilla.org/zh-CN/docs/Web/API/ArrayBuffer\",\"https://web-push-codelab.glitch.me/\",\"https://developer.mozilla.org/zh-CN/docs/Web/API/Push_API/Using_the_Push_API\",\"https://developers.google.com/web/fundamentals/codelabs/push-notifications/?hl=zh-cn\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "cn-programming",
      "permlink": "pwa-push-api",
      "title": "PWA 学习笔记之 Push API"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-28T14:10:45",
  "trx_id": "5ca0e8a903cc1554bc425d6d22a25bc57716b1db",
  "trx_in_block": 9,
  "virtual_op": 0
}
semlinkerreceived 0.048 SBD, 0.011 SP author reward for @semlinker / pwa-web-notifications-api
2018/01/27 11:23:57
authorsemlinker
permlinkpwa-web-notifications-api
sbd payout0.048 SBD
steem payout0.000 STEEM
vesting payout18.418537 VESTS
Transaction InfoBlock #19343355/Virtual Operation #3
View Raw JSON Data
{
  "block": 19343355,
  "op": [
    "author_reward",
    {
      "author": "semlinker",
      "permlink": "pwa-web-notifications-api",
      "sbd_payout": "0.048 SBD",
      "steem_payout": "0.000 STEEM",
      "vesting_payout": "18.418537 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-27T11:23:57",
  "trx_id": "0000000000000000000000000000000000000000",
  "trx_in_block": 4294967295,
  "virtual_op": 3
}
semlinkerclaimed reward balance: 0.040 SBD, 0.013 SP
2018/01/26 03:07:33
accountsemlinker
reward sbd0.040 SBD
reward steem0.000 STEEM
reward vests20.467891 VESTS
Transaction InfoBlock #19304665/Trx 2b60acbf33cfb8cb9799786870efa12c13dc3e41
View Raw JSON Data
{
  "block": 19304665,
  "op": [
    "claim_reward_balance",
    {
      "account": "semlinker",
      "reward_sbd": "0.040 SBD",
      "reward_steem": "0.000 STEEM",
      "reward_vests": "20.467891 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-26T03:07:33",
  "trx_id": "2b60acbf33cfb8cb9799786870efa12c13dc3e41",
  "trx_in_block": 36,
  "virtual_op": 0
}
semlinkerreceived 0.021 SBD, 0.008 SP author reward for @semlinker / pwa-service-workers
2018/01/25 10:08:48
authorsemlinker
permlinkpwa-service-workers
sbd payout0.021 SBD
steem payout0.000 STEEM
vesting payout12.280303 VESTS
Transaction InfoBlock #19284294/Virtual Operation #2
View Raw JSON Data
{
  "block": 19284294,
  "op": [
    "author_reward",
    {
      "author": "semlinker",
      "permlink": "pwa-service-workers",
      "sbd_payout": "0.021 SBD",
      "steem_payout": "0.000 STEEM",
      "vesting_payout": "12.280303 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-25T10:08:48",
  "trx_id": "0000000000000000000000000000000000000000",
  "trx_in_block": 4294967295,
  "virtual_op": 2
}
semlinkerreceived 0.019 SBD, 0.005 SP author reward for @semlinker / sharp
2018/01/23 16:39:54
authorsemlinker
permlinksharp
sbd payout0.019 SBD
steem payout0.000 STEEM
vesting payout8.187588 VESTS
Transaction InfoBlock #19234535/Virtual Operation #2
View Raw JSON Data
{
  "block": 19234535,
  "op": [
    "author_reward",
    {
      "author": "semlinker",
      "permlink": "sharp",
      "sbd_payout": "0.019 SBD",
      "steem_payout": "0.000 STEEM",
      "vesting_payout": "8.187588 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-23T16:39:54",
  "trx_id": "0000000000000000000000000000000000000000",
  "trx_in_block": 4294967295,
  "virtual_op": 2
}
semlinkerclaimed reward balance: 0.009 SBD, 0.004 SP
2018/01/22 01:57:48
accountsemlinker
reward sbd0.009 SBD
reward steem0.000 STEEM
reward vests6.141316 VESTS
Transaction InfoBlock #19188113/Trx 3d050bffc969b4bbe605c1993c1a6ef31990d08a
View Raw JSON Data
{
  "block": 19188113,
  "op": [
    "claim_reward_balance",
    {
      "account": "semlinker",
      "reward_sbd": "0.009 SBD",
      "reward_steem": "0.000 STEEM",
      "reward_vests": "6.141316 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-22T01:57:48",
  "trx_id": "3d050bffc969b4bbe605c1993c1a6ef31990d08a",
  "trx_in_block": 5,
  "virtual_op": 0
}
semlinkerreceived 0.009 SBD, 0.004 SP author reward for @semlinker / pwa-cachestorage-api
2018/01/21 15:34:09
authorsemlinker
permlinkpwa-cachestorage-api
sbd payout0.009 SBD
steem payout0.000 STEEM
vesting payout6.141316 VESTS
Transaction InfoBlock #19175642/Virtual Operation #14
View Raw JSON Data
{
  "block": 19175642,
  "op": [
    "author_reward",
    {
      "author": "semlinker",
      "permlink": "pwa-cachestorage-api",
      "sbd_payout": "0.009 SBD",
      "steem_payout": "0.000 STEEM",
      "vesting_payout": "6.141316 VESTS"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-21T15:34:09",
  "trx_id": "0000000000000000000000000000000000000000",
  "trx_in_block": 4294967295,
  "virtual_op": 14
}
2018/01/21 02:36:27
authorsemlinker
body@@ -313,10 +313,10 @@ )%0A%0A( +%E6%88%AA %E5%9B%BE -%E7%89%87 %E6%9D%A5%E6%BA%90%EF%BC%9A%5B @@ -353,16 +353,21 @@ nt.com/) + %E6%A1%8C%E9%9D%A2%E9%80%9A%E7%9F%A5 )%0A%0A%E5%88%9D%E7%9C%8B%E8%B5%B7%E6%9D%A5%EF%BC%8C
json metadata{"tags":["cn-programming","pwa","cn"],"image":["https://steemitimages.com/DQmfGKpZGpeap5FEuG7puqtFTCMcB9nWSfZxQewZBeZHy1M/sp-web-notifications.png","https://steemitimages.com/DQmWaC4RnrX7UGhheVPNfZ9PW7MhR1HZQWYBA71zyd4p8SW/caniuse-notifications-api.png","https://steemitimages.com/DQmVCbcMXPWkJ5Cr34iTQ8VPYRAPHvv3ptJUGucyW5PbVrk/notification-detail.png","https://steemitimages.com/DQmNudNPdUHqgDyMeq29yUPAXwwwU6JntNRdZ1z5Gyw1zke/reset-notification-permission.png"],"links":["https://www.sitepoint.com/","https://caniuse.com/","https://caniuse.com/#search=Notifications","https://gist.github.com/semlinker/ddd190ad269c0866bbd2e35b4d4009a7","https://github.com/alexgibson/notify.js","https://developer.mozilla.org/zh-CN/docs/Web/API/Notification"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkcn-programming
permlinkpwa-web-notifications-api
titlePWA 学习笔记之 Web Notifications API
Transaction InfoBlock #19160096/Trx 1d82e6407987f56aa1c63bb573297d8e237134dc
View Raw JSON Data
{
  "block": 19160096,
  "op": [
    "comment",
    {
      "author": "semlinker",
      "body": "@@ -313,10 +313,10 @@\n )%0A%0A(\n+%E6%88%AA\n %E5%9B%BE\n-%E7%89%87\n %E6%9D%A5%E6%BA%90%EF%BC%9A%5B\n@@ -353,16 +353,21 @@\n nt.com/)\n+ %E6%A1%8C%E9%9D%A2%E9%80%9A%E7%9F%A5\n )%0A%0A%E5%88%9D%E7%9C%8B%E8%B5%B7%E6%9D%A5%EF%BC%8C\n",
      "json_metadata": "{\"tags\":[\"cn-programming\",\"pwa\",\"cn\"],\"image\":[\"https://steemitimages.com/DQmfGKpZGpeap5FEuG7puqtFTCMcB9nWSfZxQewZBeZHy1M/sp-web-notifications.png\",\"https://steemitimages.com/DQmWaC4RnrX7UGhheVPNfZ9PW7MhR1HZQWYBA71zyd4p8SW/caniuse-notifications-api.png\",\"https://steemitimages.com/DQmVCbcMXPWkJ5Cr34iTQ8VPYRAPHvv3ptJUGucyW5PbVrk/notification-detail.png\",\"https://steemitimages.com/DQmNudNPdUHqgDyMeq29yUPAXwwwU6JntNRdZ1z5Gyw1zke/reset-notification-permission.png\"],\"links\":[\"https://www.sitepoint.com/\",\"https://caniuse.com/\",\"https://caniuse.com/#search=Notifications\",\"https://gist.github.com/semlinker/ddd190ad269c0866bbd2e35b4d4009a7\",\"https://github.com/alexgibson/notify.js\",\"https://developer.mozilla.org/zh-CN/docs/Web/API/Notification\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "cn-programming",
      "permlink": "pwa-web-notifications-api",
      "title": "PWA 学习笔记之 Web Notifications API"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-21T02:36:27",
  "trx_id": "1d82e6407987f56aa1c63bb573297d8e237134dc",
  "trx_in_block": 1,
  "virtual_op": 0
}
2018/01/21 02:22:57
authorsemlinker
body@@ -88,206 +88,8 @@ %E7%A4%BA%E3%80%82%0A%0A -!%5Bcover.png%5D(https://steemitimages.com/DQmVjwcAbg4L2MKTibh5xBBVPcE2BuCfuQM3AbVSCH1DbuY/cover.png)%0A%0A(%E8%83%8C%E6%99%AF%E7%B4%A0%E6%9D%90%E6%9D%A5%E6%BA%90%EF%BC%9A%5BGoogle - progressive-web-apps%5D(https://developers.google.com/web/progressive-web-apps/))%0A%0A %E8%AF%B4%E6%9D%A5%E4%B9%9F%E5%B7%A7 @@ -677,26 +677,26 @@ -api.png)%0A%0A( +%E6%88%AA %E5%9B%BE -%E7%89%87 %E6%9D%A5%E6%BA%90%EF%BC%9A%5Bcaniuse
json metadata{"tags":["cn-programming","pwa","cn"],"image":["https://steemitimages.com/DQmfGKpZGpeap5FEuG7puqtFTCMcB9nWSfZxQewZBeZHy1M/sp-web-notifications.png","https://steemitimages.com/DQmWaC4RnrX7UGhheVPNfZ9PW7MhR1HZQWYBA71zyd4p8SW/caniuse-notifications-api.png","https://steemitimages.com/DQmVCbcMXPWkJ5Cr34iTQ8VPYRAPHvv3ptJUGucyW5PbVrk/notification-detail.png","https://steemitimages.com/DQmNudNPdUHqgDyMeq29yUPAXwwwU6JntNRdZ1z5Gyw1zke/reset-notification-permission.png"],"links":["https://www.sitepoint.com/","https://caniuse.com/","https://caniuse.com/#search=Notifications","https://gist.github.com/semlinker/ddd190ad269c0866bbd2e35b4d4009a7","https://github.com/alexgibson/notify.js","https://developer.mozilla.org/zh-CN/docs/Web/API/Notification"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkcn-programming
permlinkpwa-web-notifications-api
titlePWA 学习笔记之 Web Notifications API
Transaction InfoBlock #19159826/Trx 088e9cc3b05200db44868af9360eedaa72e0048b
View Raw JSON Data
{
  "block": 19159826,
  "op": [
    "comment",
    {
      "author": "semlinker",
      "body": "@@ -88,206 +88,8 @@\n %E7%A4%BA%E3%80%82%0A%0A\n-!%5Bcover.png%5D(https://steemitimages.com/DQmVjwcAbg4L2MKTibh5xBBVPcE2BuCfuQM3AbVSCH1DbuY/cover.png)%0A%0A(%E8%83%8C%E6%99%AF%E7%B4%A0%E6%9D%90%E6%9D%A5%E6%BA%90%EF%BC%9A%5BGoogle - progressive-web-apps%5D(https://developers.google.com/web/progressive-web-apps/))%0A%0A\n %E8%AF%B4%E6%9D%A5%E4%B9%9F%E5%B7%A7\n@@ -677,26 +677,26 @@\n -api.png)%0A%0A(\n+%E6%88%AA\n %E5%9B%BE\n-%E7%89%87\n %E6%9D%A5%E6%BA%90%EF%BC%9A%5Bcaniuse \n",
      "json_metadata": "{\"tags\":[\"cn-programming\",\"pwa\",\"cn\"],\"image\":[\"https://steemitimages.com/DQmfGKpZGpeap5FEuG7puqtFTCMcB9nWSfZxQewZBeZHy1M/sp-web-notifications.png\",\"https://steemitimages.com/DQmWaC4RnrX7UGhheVPNfZ9PW7MhR1HZQWYBA71zyd4p8SW/caniuse-notifications-api.png\",\"https://steemitimages.com/DQmVCbcMXPWkJ5Cr34iTQ8VPYRAPHvv3ptJUGucyW5PbVrk/notification-detail.png\",\"https://steemitimages.com/DQmNudNPdUHqgDyMeq29yUPAXwwwU6JntNRdZ1z5Gyw1zke/reset-notification-permission.png\"],\"links\":[\"https://www.sitepoint.com/\",\"https://caniuse.com/\",\"https://caniuse.com/#search=Notifications\",\"https://gist.github.com/semlinker/ddd190ad269c0866bbd2e35b4d4009a7\",\"https://github.com/alexgibson/notify.js\",\"https://developer.mozilla.org/zh-CN/docs/Web/API/Notification\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "cn-programming",
      "permlink": "pwa-web-notifications-api",
      "title": "PWA 学习笔记之 Web Notifications API"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-21T02:22:57",
  "trx_id": "088e9cc3b05200db44868af9360eedaa72e0048b",
  "trx_in_block": 17,
  "virtual_op": 0
}
2018/01/21 02:19:45
authorsemlinker
body@@ -222,206 +222,8 @@ %E5%88%B6%E3%80%82%0A%0A -!%5Bcover.png%5D(https://steemitimages.com/DQmVjwcAbg4L2MKTibh5xBBVPcE2BuCfuQM3AbVSCH1DbuY/cover.png)%0A%0A(%E8%83%8C%E6%99%AF%E7%B4%A0%E6%9D%90%E6%9D%A5%E6%BA%90%EF%BC%9A%5BGoogle - progressive-web-apps%5D(https://developers.google.com/web/progressive-web-apps/))%0A%0A ###
json metadata{"tags":["cn-programming","pwa","cn"],"image":["https://steemitimages.com/DQmQDgeFw2e5DVoK29v2y7t2F5jeL9zPcaghR2a2F8cMVDh/sw-cache-v1.jpg","https://steemitimages.com/DQmZ1BxVxdZqS1EAdCPK7fuUz1ey5ZwNwKAi8bruNDRawxi/resource-from-sw.png","https://steemitimages.com/DQmdYavQJHrv3ENtxiWERKV5oP6oTu84GQ2b45igYwwNSfc/resource-request-fail.png"],"links":["https://steemit.com/cn-programming/@semlinker/pwa-service-workers","https://steemit.com/cn-programming/@semlinker/pwa-cachestorage-api","https://developer.mozilla.org/zh-CN/docs/Web/API/Response/Response"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkcn-programming
permlinkpwa-service-workers-cache-control
titlePWA 学习笔记之 Service Workers Cache Control
Transaction InfoBlock #19159762/Trx ca9dc2cea572d34d17228008de1b699d3a392b03
View Raw JSON Data
{
  "block": 19159762,
  "op": [
    "comment",
    {
      "author": "semlinker",
      "body": "@@ -222,206 +222,8 @@\n %E5%88%B6%E3%80%82%0A%0A\n-!%5Bcover.png%5D(https://steemitimages.com/DQmVjwcAbg4L2MKTibh5xBBVPcE2BuCfuQM3AbVSCH1DbuY/cover.png)%0A%0A(%E8%83%8C%E6%99%AF%E7%B4%A0%E6%9D%90%E6%9D%A5%E6%BA%90%EF%BC%9A%5BGoogle - progressive-web-apps%5D(https://developers.google.com/web/progressive-web-apps/))%0A%0A\n ### \n",
      "json_metadata": "{\"tags\":[\"cn-programming\",\"pwa\",\"cn\"],\"image\":[\"https://steemitimages.com/DQmQDgeFw2e5DVoK29v2y7t2F5jeL9zPcaghR2a2F8cMVDh/sw-cache-v1.jpg\",\"https://steemitimages.com/DQmZ1BxVxdZqS1EAdCPK7fuUz1ey5ZwNwKAi8bruNDRawxi/resource-from-sw.png\",\"https://steemitimages.com/DQmdYavQJHrv3ENtxiWERKV5oP6oTu84GQ2b45igYwwNSfc/resource-request-fail.png\"],\"links\":[\"https://steemit.com/cn-programming/@semlinker/pwa-service-workers\",\"https://steemit.com/cn-programming/@semlinker/pwa-cachestorage-api\",\"https://developer.mozilla.org/zh-CN/docs/Web/API/Response/Response\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "cn-programming",
      "permlink": "pwa-service-workers-cache-control",
      "title": "PWA 学习笔记之 Service Workers Cache Control"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-21T02:19:45",
  "trx_id": "ca9dc2cea572d34d17228008de1b699d3a392b03",
  "trx_in_block": 39,
  "virtual_op": 0
}
semlinkerpublished a new post: pwa-service-workers
2018/01/21 02:17:42
authorsemlinker
body@@ -182,206 +182,8 @@ %E5%BA%8F%E3%80%82%0A%0A -!%5Bcover.png%5D(https://steemitimages.com/DQmVjwcAbg4L2MKTibh5xBBVPcE2BuCfuQM3AbVSCH1DbuY/cover.png)%0A%0A(%E8%83%8C%E6%99%AF%E7%B4%A0%E6%9D%90%E6%9D%A5%E6%BA%90%EF%BC%9A%5BGoogle - progressive-web-apps%5D(https://developers.google.com/web/progressive-web-apps/))%0A%0A %E5%87%BA%E4%BA%8E%E5%AE%89%E5%85%A8 @@ -4909,145 +4909,13 @@ %E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F -%E5%A6%82%E4%B8%8B%E5%9B%BE%E6%89%80%E7%A4%BA%EF%BC%9A%0A%0A!%5Bsw-lifecycle.png%5D(https://steemitimages.com/DQmdQ9QLBDozkVi6wiFeewfqxm6KJrrUNrZ7H3re2ba9dat/sw-lifecycle.png)%0A%0A(%E5%9B%BE%E7%89%87%E6%9D%A5%E6%BA%90%EF%BC%9A%5BGoogle - +%E5%8F%AF%E4%BB%A5%E5%8F%82%E8%80%83%5B intr @@ -5053,17 +5053,17 @@ ectures) -) +%EF%BC%9A %0A%0A%E4%B8%8B%E4%B8%80%E7%AF%87%E6%96%87%E7%AB%A0%E6%88%91
json metadata{"tags":["cn-programming","pwa","cn"],"image":["https://steemitimages.com/DQmcR6xAHuAHyLKKceEzedXei8HvhwhFBvKPvTE4MWDVCiF/sw-registration.jpg","https://steemitimages.com/DQmX2Ko7BUQkmYvvBYdt36PKhfQYEZGFTNC6GCa41FCfHwb/dev-sw-tab.png","https://steemitimages.com/DQmVvPkb6Dh6HypAEfcJY7m4daJLGqaFRvsb5SNMKBohocH/sw-update.jpg"],"links":["https://support.mozilla.org/zh-CN/kb/%E9%9A%90%E7%A7%81%E6%B5%8F%E8%A7%88","https://developers.google.com/web/fundamentals/primers/service-workers/?hl=zh-cn#_2","https://caniuse.com/#search=service%20worker","https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb?hl=zh-cn","https://developers.google.com/web/ilt/pwa/introduction-to-progressive-web-app-architectures","https://developer.mozilla.org/zh-CN/docs/Web/API/Service_Worker_API","https://developers.google.com/web/fundamentals/codelabs/debugging-service-workers/?hl=zh-cn"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkcn-programming
permlinkpwa-service-workers
titlePWA 学习笔记之 Service Workers
Transaction InfoBlock #19159721/Trx 6a600864546b866ab73e9d55d2465caf7287ef11
View Raw JSON Data
{
  "block": 19159721,
  "op": [
    "comment",
    {
      "author": "semlinker",
      "body": "@@ -182,206 +182,8 @@\n %E5%BA%8F%E3%80%82%0A%0A\n-!%5Bcover.png%5D(https://steemitimages.com/DQmVjwcAbg4L2MKTibh5xBBVPcE2BuCfuQM3AbVSCH1DbuY/cover.png)%0A%0A(%E8%83%8C%E6%99%AF%E7%B4%A0%E6%9D%90%E6%9D%A5%E6%BA%90%EF%BC%9A%5BGoogle - progressive-web-apps%5D(https://developers.google.com/web/progressive-web-apps/))%0A%0A\n %E5%87%BA%E4%BA%8E%E5%AE%89%E5%85%A8\n@@ -4909,145 +4909,13 @@\n %E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F\n-%E5%A6%82%E4%B8%8B%E5%9B%BE%E6%89%80%E7%A4%BA%EF%BC%9A%0A%0A!%5Bsw-lifecycle.png%5D(https://steemitimages.com/DQmdQ9QLBDozkVi6wiFeewfqxm6KJrrUNrZ7H3re2ba9dat/sw-lifecycle.png)%0A%0A(%E5%9B%BE%E7%89%87%E6%9D%A5%E6%BA%90%EF%BC%9A%5BGoogle - \n+%E5%8F%AF%E4%BB%A5%E5%8F%82%E8%80%83%5B\n intr\n@@ -5053,17 +5053,17 @@\n ectures)\n-)\n+%EF%BC%9A\n %0A%0A%E4%B8%8B%E4%B8%80%E7%AF%87%E6%96%87%E7%AB%A0%E6%88%91\n",
      "json_metadata": "{\"tags\":[\"cn-programming\",\"pwa\",\"cn\"],\"image\":[\"https://steemitimages.com/DQmcR6xAHuAHyLKKceEzedXei8HvhwhFBvKPvTE4MWDVCiF/sw-registration.jpg\",\"https://steemitimages.com/DQmX2Ko7BUQkmYvvBYdt36PKhfQYEZGFTNC6GCa41FCfHwb/dev-sw-tab.png\",\"https://steemitimages.com/DQmVvPkb6Dh6HypAEfcJY7m4daJLGqaFRvsb5SNMKBohocH/sw-update.jpg\"],\"links\":[\"https://support.mozilla.org/zh-CN/kb/%E9%9A%90%E7%A7%81%E6%B5%8F%E8%A7%88\",\"https://developers.google.com/web/fundamentals/primers/service-workers/?hl=zh-cn#_2\",\"https://caniuse.com/#search=service%20worker\",\"https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb?hl=zh-cn\",\"https://developers.google.com/web/ilt/pwa/introduction-to-progressive-web-app-architectures\",\"https://developer.mozilla.org/zh-CN/docs/Web/API/Service_Worker_API\",\"https://developers.google.com/web/fundamentals/codelabs/debugging-service-workers/?hl=zh-cn\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "cn-programming",
      "permlink": "pwa-service-workers",
      "title": "PWA 学习笔记之 Service Workers"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-21T02:17:42",
  "trx_id": "6a600864546b866ab73e9d55d2465caf7287ef11",
  "trx_in_block": 16,
  "virtual_op": 0
}
semlinkerpublished a new post: pwa-cachestorage-api
2018/01/21 02:15:12
authorsemlinker
body@@ -91,206 +91,8 @@ %E8%BD%BD%E3%80%82%0A%0A -!%5Bcover.png%5D(https://steemitimages.com/DQmVjwcAbg4L2MKTibh5xBBVPcE2BuCfuQM3AbVSCH1DbuY/cover.png)%0A%0A(%E8%83%8C%E6%99%AF%E7%B4%A0%E6%9D%90%E6%9D%A5%E6%BA%90%EF%BC%9A%5BGoogle - progressive-web-apps%5D(https://developers.google.com/web/progressive-web-apps/))%0A%0A %E5%9C%A8 %5BP
json metadata{"tags":["cn-programming","pwa","cn"],"links":["https://steemit.com/cn-programming/@semlinker/pwa-fetch-api","https://developer.mozilla.org/zh-CN/docs/Web/API/CacheStorage"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkcn-programming
permlinkpwa-cachestorage-api
titlePWA 学习笔记之 CacheStorage API
Transaction InfoBlock #19159671/Trx dfe4ce7b905155c5a5fca9f37c7011b6ca2d96ec
View Raw JSON Data
{
  "block": 19159671,
  "op": [
    "comment",
    {
      "author": "semlinker",
      "body": "@@ -91,206 +91,8 @@\n %E8%BD%BD%E3%80%82%0A%0A\n-!%5Bcover.png%5D(https://steemitimages.com/DQmVjwcAbg4L2MKTibh5xBBVPcE2BuCfuQM3AbVSCH1DbuY/cover.png)%0A%0A(%E8%83%8C%E6%99%AF%E7%B4%A0%E6%9D%90%E6%9D%A5%E6%BA%90%EF%BC%9A%5BGoogle - progressive-web-apps%5D(https://developers.google.com/web/progressive-web-apps/))%0A%0A\n %E5%9C%A8 %5BP\n",
      "json_metadata": "{\"tags\":[\"cn-programming\",\"pwa\",\"cn\"],\"links\":[\"https://steemit.com/cn-programming/@semlinker/pwa-fetch-api\",\"https://developer.mozilla.org/zh-CN/docs/Web/API/CacheStorage\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "cn-programming",
      "permlink": "pwa-cachestorage-api",
      "title": "PWA 学习笔记之 CacheStorage API"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-21T02:15:12",
  "trx_id": "dfe4ce7b905155c5a5fca9f37c7011b6ca2d96ec",
  "trx_in_block": 13,
  "virtual_op": 0
}
2018/01/21 02:14:54
idfollow
json["follow",{"follower":"semlinker","following":"cn-naughty.boy","what":["ignore"]}]
required auths[]
required posting auths["semlinker"]
Transaction InfoBlock #19159665/Trx ac9164d716b021ff47efc7fe24f200cb6d6f7471
View Raw JSON Data
{
  "block": 19159665,
  "op": [
    "custom_json",
    {
      "id": "follow",
      "json": "[\"follow\",{\"follower\":\"semlinker\",\"following\":\"cn-naughty.boy\",\"what\":[\"ignore\"]}]",
      "required_auths": [],
      "required_posting_auths": [
        "semlinker"
      ]
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-21T02:14:54",
  "trx_id": "ac9164d716b021ff47efc7fe24f200cb6d6f7471",
  "trx_in_block": 23,
  "virtual_op": 0
}
2018/01/21 02:12:57
idfollow
json["follow",{"follower":"semlinker","following":"steemitboard","what":["ignore"]}]
required auths[]
required posting auths["semlinker"]
Transaction InfoBlock #19159626/Trx 80ff2259cfef53c225b5d592037bd851065b7de7
View Raw JSON Data
{
  "block": 19159626,
  "op": [
    "custom_json",
    {
      "id": "follow",
      "json": "[\"follow\",{\"follower\":\"semlinker\",\"following\":\"steemitboard\",\"what\":[\"ignore\"]}]",
      "required_auths": [],
      "required_posting_auths": [
        "semlinker"
      ]
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-21T02:12:57",
  "trx_id": "80ff2259cfef53c225b5d592037bd851065b7de7",
  "trx_in_block": 28,
  "virtual_op": 0
}
2018/01/21 02:12:54
idfollow
json["follow",{"follower":"semlinker","following":"steemitboard","what":[]}]
required auths[]
required posting auths["semlinker"]
Transaction InfoBlock #19159625/Trx 3ed8e7d0cb9782acb49ce4b9019fb47a35884c59
View Raw JSON Data
{
  "block": 19159625,
  "op": [
    "custom_json",
    {
      "id": "follow",
      "json": "[\"follow\",{\"follower\":\"semlinker\",\"following\":\"steemitboard\",\"what\":[]}]",
      "required_auths": [],
      "required_posting_auths": [
        "semlinker"
      ]
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-21T02:12:54",
  "trx_id": "3ed8e7d0cb9782acb49ce4b9019fb47a35884c59",
  "trx_in_block": 18,
  "virtual_op": 0
}
2018/01/21 01:38:24
authorsemlinker
body@@ -86,37 +86,21 @@ %E5%B8%B8%E6%98%BE%E7%A4%BA%E3%80%82%0A%0A!%5B -web-notifications-api +cover .png%5D(ht @@ -130,74 +130,58 @@ /DQm -Z2hkDxr5t3qdLaf3qvPEgLQd9q2U3Cn2v1dJjKGZTNHh/web-notifications-api +VjwcAbg4L2MKTibh5xBBVPcE2BuCfuQM3AbVSCH1DbuY/cover .png
json metadata{"tags":["cn-programming","pwa","cn"],"image":["https://steemitimages.com/DQmVjwcAbg4L2MKTibh5xBBVPcE2BuCfuQM3AbVSCH1DbuY/cover.png","https://steemitimages.com/DQmfGKpZGpeap5FEuG7puqtFTCMcB9nWSfZxQewZBeZHy1M/sp-web-notifications.png","https://steemitimages.com/DQmWaC4RnrX7UGhheVPNfZ9PW7MhR1HZQWYBA71zyd4p8SW/caniuse-notifications-api.png","https://steemitimages.com/DQmVCbcMXPWkJ5Cr34iTQ8VPYRAPHvv3ptJUGucyW5PbVrk/notification-detail.png","https://steemitimages.com/DQmNudNPdUHqgDyMeq29yUPAXwwwU6JntNRdZ1z5Gyw1zke/reset-notification-permission.png"],"links":["https://developers.google.com/web/progressive-web-apps/","https://www.sitepoint.com/","https://caniuse.com/","https://caniuse.com/#search=Notifications","https://gist.github.com/semlinker/ddd190ad269c0866bbd2e35b4d4009a7","https://github.com/alexgibson/notify.js","https://developer.mozilla.org/zh-CN/docs/Web/API/Notification"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkcn-programming
permlinkpwa-web-notifications-api
titlePWA 学习笔记之 Web Notifications API
Transaction InfoBlock #19158935/Trx 2f3c7462daa37c9d8a631348a659181d162f06fd
View Raw JSON Data
{
  "block": 19158935,
  "op": [
    "comment",
    {
      "author": "semlinker",
      "body": "@@ -86,37 +86,21 @@\n %E5%B8%B8%E6%98%BE%E7%A4%BA%E3%80%82%0A%0A!%5B\n-web-notifications-api\n+cover\n .png%5D(ht\n@@ -130,74 +130,58 @@\n /DQm\n-Z2hkDxr5t3qdLaf3qvPEgLQd9q2U3Cn2v1dJjKGZTNHh/web-notifications-api\n+VjwcAbg4L2MKTibh5xBBVPcE2BuCfuQM3AbVSCH1DbuY/cover\n .png\n",
      "json_metadata": "{\"tags\":[\"cn-programming\",\"pwa\",\"cn\"],\"image\":[\"https://steemitimages.com/DQmVjwcAbg4L2MKTibh5xBBVPcE2BuCfuQM3AbVSCH1DbuY/cover.png\",\"https://steemitimages.com/DQmfGKpZGpeap5FEuG7puqtFTCMcB9nWSfZxQewZBeZHy1M/sp-web-notifications.png\",\"https://steemitimages.com/DQmWaC4RnrX7UGhheVPNfZ9PW7MhR1HZQWYBA71zyd4p8SW/caniuse-notifications-api.png\",\"https://steemitimages.com/DQmVCbcMXPWkJ5Cr34iTQ8VPYRAPHvv3ptJUGucyW5PbVrk/notification-detail.png\",\"https://steemitimages.com/DQmNudNPdUHqgDyMeq29yUPAXwwwU6JntNRdZ1z5Gyw1zke/reset-notification-permission.png\"],\"links\":[\"https://developers.google.com/web/progressive-web-apps/\",\"https://www.sitepoint.com/\",\"https://caniuse.com/\",\"https://caniuse.com/#search=Notifications\",\"https://gist.github.com/semlinker/ddd190ad269c0866bbd2e35b4d4009a7\",\"https://github.com/alexgibson/notify.js\",\"https://developer.mozilla.org/zh-CN/docs/Web/API/Notification\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "cn-programming",
      "permlink": "pwa-web-notifications-api",
      "title": "PWA 学习笔记之 Web Notifications API"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-21T01:38:24",
  "trx_id": "2f3c7462daa37c9d8a631348a659181d162f06fd",
  "trx_in_block": 16,
  "virtual_op": 0
}
2018/01/21 01:36:00
authorsemlinker
body@@ -220,33 +220,21 @@ %E5%AD%98%E6%8E%A7%E5%88%B6%E3%80%82%0A%0A!%5B -sws-cache-control +cover .png%5D(ht @@ -264,70 +264,58 @@ /DQm -P1EF4C18okZh85mv8MpR9M8CzJ6W6X4WkbWF6SXTNVDj/sws-cache-control +VjwcAbg4L2MKTibh5xBBVPcE2BuCfuQM3AbVSCH1DbuY/cover .png
json metadata{"tags":["cn-programming","pwa","cn"],"image":["https://steemitimages.com/DQmVjwcAbg4L2MKTibh5xBBVPcE2BuCfuQM3AbVSCH1DbuY/cover.png","https://steemitimages.com/DQmQDgeFw2e5DVoK29v2y7t2F5jeL9zPcaghR2a2F8cMVDh/sw-cache-v1.jpg","https://steemitimages.com/DQmZ1BxVxdZqS1EAdCPK7fuUz1ey5ZwNwKAi8bruNDRawxi/resource-from-sw.png","https://steemitimages.com/DQmdYavQJHrv3ENtxiWERKV5oP6oTu84GQ2b45igYwwNSfc/resource-request-fail.png"],"links":["https://steemit.com/cn-programming/@semlinker/pwa-service-workers","https://developers.google.com/web/progressive-web-apps/","https://steemit.com/cn-programming/@semlinker/pwa-cachestorage-api","https://developer.mozilla.org/zh-CN/docs/Web/API/Response/Response"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkcn-programming
permlinkpwa-service-workers-cache-control
titlePWA 学习笔记之 Service Workers Cache Control
Transaction InfoBlock #19158887/Trx fb546623114402388203e8aee9e10d59d85c0b76
View Raw JSON Data
{
  "block": 19158887,
  "op": [
    "comment",
    {
      "author": "semlinker",
      "body": "@@ -220,33 +220,21 @@\n %E5%AD%98%E6%8E%A7%E5%88%B6%E3%80%82%0A%0A!%5B\n-sws-cache-control\n+cover\n .png%5D(ht\n@@ -264,70 +264,58 @@\n /DQm\n-P1EF4C18okZh85mv8MpR9M8CzJ6W6X4WkbWF6SXTNVDj/sws-cache-control\n+VjwcAbg4L2MKTibh5xBBVPcE2BuCfuQM3AbVSCH1DbuY/cover\n .png\n",
      "json_metadata": "{\"tags\":[\"cn-programming\",\"pwa\",\"cn\"],\"image\":[\"https://steemitimages.com/DQmVjwcAbg4L2MKTibh5xBBVPcE2BuCfuQM3AbVSCH1DbuY/cover.png\",\"https://steemitimages.com/DQmQDgeFw2e5DVoK29v2y7t2F5jeL9zPcaghR2a2F8cMVDh/sw-cache-v1.jpg\",\"https://steemitimages.com/DQmZ1BxVxdZqS1EAdCPK7fuUz1ey5ZwNwKAi8bruNDRawxi/resource-from-sw.png\",\"https://steemitimages.com/DQmdYavQJHrv3ENtxiWERKV5oP6oTu84GQ2b45igYwwNSfc/resource-request-fail.png\"],\"links\":[\"https://steemit.com/cn-programming/@semlinker/pwa-service-workers\",\"https://developers.google.com/web/progressive-web-apps/\",\"https://steemit.com/cn-programming/@semlinker/pwa-cachestorage-api\",\"https://developer.mozilla.org/zh-CN/docs/Web/API/Response/Response\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "cn-programming",
      "permlink": "pwa-service-workers-cache-control",
      "title": "PWA 学习笔记之 Service Workers Cache Control"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-21T01:36:00",
  "trx_id": "fb546623114402388203e8aee9e10d59d85c0b76",
  "trx_in_block": 34,
  "virtual_op": 0
}
semlinkerpublished a new post: pwa-service-workers
2018/01/21 01:33:27
authorsemlinker
body@@ -180,28 +180,19 @@ %E7%94%A8%E7%A8%8B%E5%BA%8F%E3%80%82%0A%0A!%5B -service-work +cov er.png%5D( @@ -224,65 +224,56 @@ /DQm -RUzuKqD9yraRvRGWtePCcc4tvKssCVcxpLoxziPr4fsf/service-work +VjwcAbg4L2MKTibh5xBBVPcE2BuCfuQM3AbVSCH1DbuY/cov er.p
json metadata{"tags":["cn-programming","pwa","cn"],"image":["https://steemitimages.com/DQmVjwcAbg4L2MKTibh5xBBVPcE2BuCfuQM3AbVSCH1DbuY/cover.png","https://steemitimages.com/DQmcR6xAHuAHyLKKceEzedXei8HvhwhFBvKPvTE4MWDVCiF/sw-registration.jpg","https://steemitimages.com/DQmX2Ko7BUQkmYvvBYdt36PKhfQYEZGFTNC6GCa41FCfHwb/dev-sw-tab.png","https://steemitimages.com/DQmVvPkb6Dh6HypAEfcJY7m4daJLGqaFRvsb5SNMKBohocH/sw-update.jpg","https://steemitimages.com/DQmdQ9QLBDozkVi6wiFeewfqxm6KJrrUNrZ7H3re2ba9dat/sw-lifecycle.png"],"links":["https://developers.google.com/web/progressive-web-apps/","https://support.mozilla.org/zh-CN/kb/%E9%9A%90%E7%A7%81%E6%B5%8F%E8%A7%88","https://developers.google.com/web/fundamentals/primers/service-workers/?hl=zh-cn#_2","https://caniuse.com/#search=service%20worker","https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb?hl=zh-cn","https://developers.google.com/web/ilt/pwa/introduction-to-progressive-web-app-architectures","https://developer.mozilla.org/zh-CN/docs/Web/API/Service_Worker_API","https://developers.google.com/web/fundamentals/codelabs/debugging-service-workers/?hl=zh-cn"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkcn-programming
permlinkpwa-service-workers
titlePWA 学习笔记之 Service Workers
Transaction InfoBlock #19158836/Trx 90b5ddd87975cc78bc681922f25112af430d62af
View Raw JSON Data
{
  "block": 19158836,
  "op": [
    "comment",
    {
      "author": "semlinker",
      "body": "@@ -180,28 +180,19 @@\n %E7%94%A8%E7%A8%8B%E5%BA%8F%E3%80%82%0A%0A!%5B\n-service-work\n+cov\n er.png%5D(\n@@ -224,65 +224,56 @@\n /DQm\n-RUzuKqD9yraRvRGWtePCcc4tvKssCVcxpLoxziPr4fsf/service-work\n+VjwcAbg4L2MKTibh5xBBVPcE2BuCfuQM3AbVSCH1DbuY/cov\n er.p\n",
      "json_metadata": "{\"tags\":[\"cn-programming\",\"pwa\",\"cn\"],\"image\":[\"https://steemitimages.com/DQmVjwcAbg4L2MKTibh5xBBVPcE2BuCfuQM3AbVSCH1DbuY/cover.png\",\"https://steemitimages.com/DQmcR6xAHuAHyLKKceEzedXei8HvhwhFBvKPvTE4MWDVCiF/sw-registration.jpg\",\"https://steemitimages.com/DQmX2Ko7BUQkmYvvBYdt36PKhfQYEZGFTNC6GCa41FCfHwb/dev-sw-tab.png\",\"https://steemitimages.com/DQmVvPkb6Dh6HypAEfcJY7m4daJLGqaFRvsb5SNMKBohocH/sw-update.jpg\",\"https://steemitimages.com/DQmdQ9QLBDozkVi6wiFeewfqxm6KJrrUNrZ7H3re2ba9dat/sw-lifecycle.png\"],\"links\":[\"https://developers.google.com/web/progressive-web-apps/\",\"https://support.mozilla.org/zh-CN/kb/%E9%9A%90%E7%A7%81%E6%B5%8F%E8%A7%88\",\"https://developers.google.com/web/fundamentals/primers/service-workers/?hl=zh-cn#_2\",\"https://caniuse.com/#search=service%20worker\",\"https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb?hl=zh-cn\",\"https://developers.google.com/web/ilt/pwa/introduction-to-progressive-web-app-architectures\",\"https://developer.mozilla.org/zh-CN/docs/Web/API/Service_Worker_API\",\"https://developers.google.com/web/fundamentals/codelabs/debugging-service-workers/?hl=zh-cn\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "cn-programming",
      "permlink": "pwa-service-workers",
      "title": "PWA 学习笔记之 Service Workers"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-21T01:33:27",
  "trx_id": "90b5ddd87975cc78bc681922f25112af430d62af",
  "trx_in_block": 4,
  "virtual_op": 0
}
semlinkerpublished a new post: pwa-cachestorage-api
2018/01/21 01:23:45
authorsemlinker
body@@ -90,32 +90,20 @@ %E5%8A%A0%E8%BD%BD%E3%80%82%0A%0A!%5Bc -ache-storage-api +over .png%5D(ht @@ -133,70 +133,58 @@ /DQm -bvVXMTUosxY9Rr8y5bsWpTGdQxgC7FUZHx4JpY6QEmc6/cache-storage-api +VjwcAbg4L2MKTibh5xBBVPcE2BuCfuQM3AbVSCH1DbuY/cover .png
json metadata{"tags":["cn-programming","pwa","cn"],"links":["https://developers.google.com/web/progressive-web-apps/","https://steemit.com/cn-programming/@semlinker/pwa-fetch-api","https://developer.mozilla.org/zh-CN/docs/Web/API/CacheStorage"],"app":"steemit/0.1","format":"markdown","image":["https://steemitimages.com/DQmVjwcAbg4L2MKTibh5xBBVPcE2BuCfuQM3AbVSCH1DbuY/cover.png"]}
parent author
parent permlinkcn-programming
permlinkpwa-cachestorage-api
titlePWA 学习笔记之 CacheStorage API
Transaction InfoBlock #19158643/Trx 9c5ca43c0f9ab1c371bc465f5053ce54dc3fa60f
View Raw JSON Data
{
  "block": 19158643,
  "op": [
    "comment",
    {
      "author": "semlinker",
      "body": "@@ -90,32 +90,20 @@\n %E5%8A%A0%E8%BD%BD%E3%80%82%0A%0A!%5Bc\n-ache-storage-api\n+over\n .png%5D(ht\n@@ -133,70 +133,58 @@\n /DQm\n-bvVXMTUosxY9Rr8y5bsWpTGdQxgC7FUZHx4JpY6QEmc6/cache-storage-api\n+VjwcAbg4L2MKTibh5xBBVPcE2BuCfuQM3AbVSCH1DbuY/cover\n .png\n",
      "json_metadata": "{\"tags\":[\"cn-programming\",\"pwa\",\"cn\"],\"links\":[\"https://developers.google.com/web/progressive-web-apps/\",\"https://steemit.com/cn-programming/@semlinker/pwa-fetch-api\",\"https://developer.mozilla.org/zh-CN/docs/Web/API/CacheStorage\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\",\"image\":[\"https://steemitimages.com/DQmVjwcAbg4L2MKTibh5xBBVPcE2BuCfuQM3AbVSCH1DbuY/cover.png\"]}",
      "parent_author": "",
      "parent_permlink": "cn-programming",
      "permlink": "pwa-cachestorage-api",
      "title": "PWA 学习笔记之 CacheStorage API"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-21T01:23:45",
  "trx_id": "9c5ca43c0f9ab1c371bc465f5053ce54dc3fa60f",
  "trx_in_block": 1,
  "virtual_op": 0
}
2018/01/21 00:10:39
authorsemlinker
bodyThanks,I had a try and saw my records,wonderful !
json metadata{"tags":["steem"],"app":"steemit/0.1"}
parent authorpenguinpablo
parent permlinkannouncing-steemblockexplorer-com
permlinkre-penguinpablo-announcing-steemblockexplorer-com-20180121t001039954z
title
Transaction InfoBlock #19157181/Trx 13777c1cc00b700fefdc231d37d1e1ffb3a5af03
View Raw JSON Data
{
  "block": 19157181,
  "op": [
    "comment",
    {
      "author": "semlinker",
      "body": "Thanks,I had a try and saw my records,wonderful !",
      "json_metadata": "{\"tags\":[\"steem\"],\"app\":\"steemit/0.1\"}",
      "parent_author": "penguinpablo",
      "parent_permlink": "announcing-steemblockexplorer-com",
      "permlink": "re-penguinpablo-announcing-steemblockexplorer-com-20180121t001039954z",
      "title": ""
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-21T00:10:39",
  "trx_id": "13777c1cc00b700fefdc231d37d1e1ffb3a5af03",
  "trx_in_block": 28,
  "virtual_op": 0
}
2018/01/21 00:03:45
authorpenguinpablo
permlinkannouncing-steemblockexplorer-com
votersemlinker
weight10000 (100.00%)
Transaction InfoBlock #19157043/Trx 7ba7a038ae547523d5f8298078f5e1e188cb846d
View Raw JSON Data
{
  "block": 19157043,
  "op": [
    "vote",
    {
      "author": "penguinpablo",
      "permlink": "announcing-steemblockexplorer-com",
      "voter": "semlinker",
      "weight": 10000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-21T00:03:45",
  "trx_id": "7ba7a038ae547523d5f8298078f5e1e188cb846d",
  "trx_in_block": 36,
  "virtual_op": 0
}
2018/01/20 23:51:21
authorsteemitboard
permlinkhttp-i-cubeupload-com-7ciqeo-png
votersemlinker
weight10000 (100.00%)
Transaction InfoBlock #19156795/Trx a6e1fb9f9441c7e8f226ef78872aef35994b6516
View Raw JSON Data
{
  "block": 19156795,
  "op": [
    "vote",
    {
      "author": "steemitboard",
      "permlink": "http-i-cubeupload-com-7ciqeo-png",
      "voter": "semlinker",
      "weight": 10000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-20T23:51:21",
  "trx_id": "a6e1fb9f9441c7e8f226ef78872aef35994b6516",
  "trx_in_block": 67,
  "virtual_op": 0
}
2018/01/20 23:50:27
authorsteemitboard
permlinksteemitboard-notify-semlinker-20180120t163738000z
votersemlinker
weight10000 (100.00%)
Transaction InfoBlock #19156777/Trx 1d1761f4d48fe4290bb4f260b88d0da6fae598af
View Raw JSON Data
{
  "block": 19156777,
  "op": [
    "vote",
    {
      "author": "steemitboard",
      "permlink": "steemitboard-notify-semlinker-20180120t163738000z",
      "voter": "semlinker",
      "weight": 10000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-20T23:50:27",
  "trx_id": "1d1761f4d48fe4290bb4f260b88d0da6fae598af",
  "trx_in_block": 53,
  "virtual_op": 0
}
2018/01/20 23:48:30
idfollow
json["follow",{"follower":"semlinker","following":"steemitboard","what":["blog"]}]
required auths[]
required posting auths["semlinker"]
Transaction InfoBlock #19156738/Trx 1edbba72783fa79a0c020dea56730152d3fa7188
View Raw JSON Data
{
  "block": 19156738,
  "op": [
    "custom_json",
    {
      "id": "follow",
      "json": "[\"follow\",{\"follower\":\"semlinker\",\"following\":\"steemitboard\",\"what\":[\"blog\"]}]",
      "required_auths": [],
      "required_posting_auths": [
        "semlinker"
      ]
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-20T23:48:30",
  "trx_id": "1edbba72783fa79a0c020dea56730152d3fa7188",
  "trx_in_block": 46,
  "virtual_op": 0
}
2018/01/20 16:37:39
authorsemlinker
permlinkpwa-web-notifications-api
votersteemitboard
weight100 (1.00%)
Transaction InfoBlock #19148125/Trx 7be68c462c2ae698817147d54b3b79b3a80942e0
View Raw JSON Data
{
  "block": 19148125,
  "op": [
    "vote",
    {
      "author": "semlinker",
      "permlink": "pwa-web-notifications-api",
      "voter": "steemitboard",
      "weight": 100
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-20T16:37:39",
  "trx_id": "7be68c462c2ae698817147d54b3b79b3a80942e0",
  "trx_in_block": 12,
  "virtual_op": 0
}
2018/01/20 16:37:36
authorsteemitboard
bodyCongratulations @semlinker! You have completed some achievement on Steemit and have been rewarded with new badge(s) : [![](https://steemitimages.com/70x80/http://steemitboard.com/notifications/posts.png)](http://steemitboard.com/@semlinker) Award for the number of posts published Click on any badge to view your own Board of Honor on SteemitBoard. For more information about SteemitBoard, click [here](https://steemit.com/@steemitboard) If you no longer want to receive notifications, reply to this comment with the word `STOP` > By upvoting this notification, you can help all Steemit users. Learn how [here](https://steemit.com/steemitboard/@steemitboard/http-i-cubeupload-com-7ciqeo-png)!
json metadata{"image":["https://steemitboard.com/img/notifications.png"]}
parent authorsemlinker
parent permlinkpwa-web-notifications-api
permlinksteemitboard-notify-semlinker-20180120t163738000z
title
Transaction InfoBlock #19148124/Trx 46132fe1b0b561881fd4ca02545212d22d1a505c
View Raw JSON Data
{
  "block": 19148124,
  "op": [
    "comment",
    {
      "author": "steemitboard",
      "body": "Congratulations @semlinker! You have completed some achievement on Steemit and have been rewarded with new badge(s) :\n\n[![](https://steemitimages.com/70x80/http://steemitboard.com/notifications/posts.png)](http://steemitboard.com/@semlinker) Award for the number of posts published\n\nClick on any badge to view your own Board of Honor on SteemitBoard.\nFor more information about SteemitBoard, click [here](https://steemit.com/@steemitboard)\n\nIf you no longer want to receive notifications, reply to this comment with the word `STOP`\n\n> By upvoting this notification, you can help all Steemit users. Learn how [here](https://steemit.com/steemitboard/@steemitboard/http-i-cubeupload-com-7ciqeo-png)!",
      "json_metadata": "{\"image\":[\"https://steemitboard.com/img/notifications.png\"]}",
      "parent_author": "semlinker",
      "parent_permlink": "pwa-web-notifications-api",
      "permlink": "steemitboard-notify-semlinker-20180120t163738000z",
      "title": ""
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-20T16:37:36",
  "trx_id": "46132fe1b0b561881fd4ca02545212d22d1a505c",
  "trx_in_block": 160,
  "virtual_op": 0
}
2018/01/20 12:26:03
authorsemlinker
body@@ -1950,16 +1950,80 @@ else %7B%0A + // %E5%8F%AF%E8%83%BD%E7%9A%84%E7%8A%B6%E6%80%81%E4%B8%BA%EF%BC%9Adenied%E6%88%96default%EF%BC%8C%E8%8B%A5%E7%8A%B6%E6%80%81%E4%B8%BAdenied%E5%88%99requestPermission%E6%96%B9%E6%B3%95%E6%97%A0%E6%95%88%0A N @@ -4104,17 +4104,17 @@ %E7%9F%A5%E8%AF%86%E3%80%82%E5%AE%8C%E6%95%B4%E7%9A%84%E7%A4%BA%E4%BE%8B -%E6%BA%90 +%E4%BB%A3 %E7%A0%81%EF%BC%8C%E5%B7%B2%E6%94%BE%E5%88%B0 %5BG @@ -4202,16 +4202,136 @@ %E4%BC%B4%E5%8F%AF%E4%BB%A5%E5%8F%82%E8%80%83%E4%B8%80%E4%B8%8B%E3%80%82 +%E5%8F%A6%E5%A4%96 Github %E4%B8%8A%E6%9C%89%E4%B8%AA%E5%90%8D%E4%B8%BA %5Bnotify.js%5D(https://github.com/alexgibson/notify.js) %E7%9A%84%E9%A1%B9%E7%9B%AE%EF%BC%8C%E8%AF%A5%E9%A1%B9%E7%9B%AE%E5%AF%B9 Web Notifications API %E8%BF%9B%E8%A1%8C%E4%BA%86%E5%B0%81%E8%A3%85%EF%BC%8C%E6%84%9F%E5%85%B4%E8%B6%A3%E7%9A%84%E5%B0%8F%E4%BC%99%E4%BC%B4%E5%8F%AF%E4%BB%A5%E4%BA%86%E8%A7%A3%E4%B8%80%E4%B8%8B%E3%80%82 %E4%B8%8B%E4%B8%80%E7%AF%87%E6%96%87%E7%AB%A0%EF%BC%8C%E6%88%91%E4%BB%AC
json metadata{"tags":["cn-programming","pwa","cn"],"image":["https://steemitimages.com/DQmZ2hkDxr5t3qdLaf3qvPEgLQd9q2U3Cn2v1dJjKGZTNHh/web-notifications-api.png","https://steemitimages.com/DQmfGKpZGpeap5FEuG7puqtFTCMcB9nWSfZxQewZBeZHy1M/sp-web-notifications.png","https://steemitimages.com/DQmWaC4RnrX7UGhheVPNfZ9PW7MhR1HZQWYBA71zyd4p8SW/caniuse-notifications-api.png","https://steemitimages.com/DQmVCbcMXPWkJ5Cr34iTQ8VPYRAPHvv3ptJUGucyW5PbVrk/notification-detail.png","https://steemitimages.com/DQmNudNPdUHqgDyMeq29yUPAXwwwU6JntNRdZ1z5Gyw1zke/reset-notification-permission.png"],"links":["https://developers.google.com/web/progressive-web-apps/","https://www.sitepoint.com/","https://caniuse.com/","https://caniuse.com/#search=Notifications","https://gist.github.com/semlinker/ddd190ad269c0866bbd2e35b4d4009a7","https://github.com/alexgibson/notify.js","https://developer.mozilla.org/zh-CN/docs/Web/API/Notification"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkcn-programming
permlinkpwa-web-notifications-api
titlePWA 学习笔记之 Web Notifications API
Transaction InfoBlock #19143093/Trx 1d6ec212973aab2141d2c4bb630d4b730dd1b59f
View Raw JSON Data
{
  "block": 19143093,
  "op": [
    "comment",
    {
      "author": "semlinker",
      "body": "@@ -1950,16 +1950,80 @@\n  else %7B%0A\n+      // %E5%8F%AF%E8%83%BD%E7%9A%84%E7%8A%B6%E6%80%81%E4%B8%BA%EF%BC%9Adenied%E6%88%96default%EF%BC%8C%E8%8B%A5%E7%8A%B6%E6%80%81%E4%B8%BAdenied%E5%88%99requestPermission%E6%96%B9%E6%B3%95%E6%97%A0%E6%95%88%0A\n        N\n@@ -4104,17 +4104,17 @@\n %E7%9F%A5%E8%AF%86%E3%80%82%E5%AE%8C%E6%95%B4%E7%9A%84%E7%A4%BA%E4%BE%8B\n-%E6%BA%90\n+%E4%BB%A3\n %E7%A0%81%EF%BC%8C%E5%B7%B2%E6%94%BE%E5%88%B0 %5BG\n@@ -4202,16 +4202,136 @@\n %E4%BC%B4%E5%8F%AF%E4%BB%A5%E5%8F%82%E8%80%83%E4%B8%80%E4%B8%8B%E3%80%82\n+%E5%8F%A6%E5%A4%96 Github %E4%B8%8A%E6%9C%89%E4%B8%AA%E5%90%8D%E4%B8%BA %5Bnotify.js%5D(https://github.com/alexgibson/notify.js) %E7%9A%84%E9%A1%B9%E7%9B%AE%EF%BC%8C%E8%AF%A5%E9%A1%B9%E7%9B%AE%E5%AF%B9 Web Notifications API %E8%BF%9B%E8%A1%8C%E4%BA%86%E5%B0%81%E8%A3%85%EF%BC%8C%E6%84%9F%E5%85%B4%E8%B6%A3%E7%9A%84%E5%B0%8F%E4%BC%99%E4%BC%B4%E5%8F%AF%E4%BB%A5%E4%BA%86%E8%A7%A3%E4%B8%80%E4%B8%8B%E3%80%82\n %E4%B8%8B%E4%B8%80%E7%AF%87%E6%96%87%E7%AB%A0%EF%BC%8C%E6%88%91%E4%BB%AC\n",
      "json_metadata": "{\"tags\":[\"cn-programming\",\"pwa\",\"cn\"],\"image\":[\"https://steemitimages.com/DQmZ2hkDxr5t3qdLaf3qvPEgLQd9q2U3Cn2v1dJjKGZTNHh/web-notifications-api.png\",\"https://steemitimages.com/DQmfGKpZGpeap5FEuG7puqtFTCMcB9nWSfZxQewZBeZHy1M/sp-web-notifications.png\",\"https://steemitimages.com/DQmWaC4RnrX7UGhheVPNfZ9PW7MhR1HZQWYBA71zyd4p8SW/caniuse-notifications-api.png\",\"https://steemitimages.com/DQmVCbcMXPWkJ5Cr34iTQ8VPYRAPHvv3ptJUGucyW5PbVrk/notification-detail.png\",\"https://steemitimages.com/DQmNudNPdUHqgDyMeq29yUPAXwwwU6JntNRdZ1z5Gyw1zke/reset-notification-permission.png\"],\"links\":[\"https://developers.google.com/web/progressive-web-apps/\",\"https://www.sitepoint.com/\",\"https://caniuse.com/\",\"https://caniuse.com/#search=Notifications\",\"https://gist.github.com/semlinker/ddd190ad269c0866bbd2e35b4d4009a7\",\"https://github.com/alexgibson/notify.js\",\"https://developer.mozilla.org/zh-CN/docs/Web/API/Notification\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "cn-programming",
      "permlink": "pwa-web-notifications-api",
      "title": "PWA 学习笔记之 Web Notifications API"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-20T12:26:03",
  "trx_id": "1d6ec212973aab2141d2c4bb630d4b730dd1b59f",
  "trx_in_block": 11,
  "virtual_op": 0
}
2018/01/20 11:25:51
authorcn-naughty.boy
body看到你的帖子,真是我的幸运啊!太棒了!
json metadata{"tags":["cn"]}
parent authorsemlinker
parent permlinkpwa-web-notifications-api
permlink20180120t112549985z-post
title
Transaction InfoBlock #19141889/Trx 359c8b9e968f8d890ee018f16b0c74ae0872ce29
View Raw JSON Data
{
  "block": 19141889,
  "op": [
    "comment",
    {
      "author": "cn-naughty.boy",
      "body": "看到你的帖子,真是我的幸运啊!太棒了!",
      "json_metadata": "{\"tags\":[\"cn\"]}",
      "parent_author": "semlinker",
      "parent_permlink": "pwa-web-notifications-api",
      "permlink": "20180120t112549985z-post",
      "title": ""
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-20T11:25:51",
  "trx_id": "359c8b9e968f8d890ee018f16b0c74ae0872ce29",
  "trx_in_block": 25,
  "virtual_op": 0
}
2018/01/20 11:25:48
authorsemlinker
permlinkpwa-web-notifications-api
votercn-naughty.boy
weight4619 (46.19%)
Transaction InfoBlock #19141888/Trx a24f788b8f5dbe16bb46d27a5b10019990cfb520
View Raw JSON Data
{
  "block": 19141888,
  "op": [
    "vote",
    {
      "author": "semlinker",
      "permlink": "pwa-web-notifications-api",
      "voter": "cn-naughty.boy",
      "weight": 4619
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-20T11:25:48",
  "trx_id": "a24f788b8f5dbe16bb46d27a5b10019990cfb520",
  "trx_in_block": 33,
  "virtual_op": 0
}
2018/01/20 11:23:57
authorsemlinker
bodyWeb Notifications API 允许网页向最终用户显示系统通知,这些通知在顶级浏览器上下文窗口之外,因此即使用户已经切换标签页或移动到不同的应用程序,也可以正常显示。 ![web-notifications-api.png](https://steemitimages.com/DQmZ2hkDxr5t3qdLaf3qvPEgLQd9q2U3Cn2v1dJjKGZTNHh/web-notifications-api.png) (背景素材来源:[Google - progressive-web-apps](https://developers.google.com/web/progressive-web-apps/)) 说来也巧,在思考如何下笔时,刚好收到 [sitepoint](https://www.sitepoint.com/) 发来的通知。它竟然自己送上门来,那我就不客气了,直接拿它 "开刀"。 ![sp-web-notifications.png](https://steemitimages.com/DQmfGKpZGpeap5FEuG7puqtFTCMcB9nWSfZxQewZBeZHy1M/sp-web-notifications.png) (图片来源:[sitepoint](https://www.sitepoint.com/)) 初看起来,觉得挺简单的,但实际动手前却不知道如何下手,所以还是得乖乖地补一下 Web Notifications API 相关的基础知识。撸新的 API 前,直觉告诉我,还是得先了解一下其兼容性,这个任务当然还是交给我们的 [caniuse](https://caniuse.com/) 啦。写本文时,Web Notifications API 的兼容性如下图所示: ![caniuse-notifications-api.png](https://steemitimages.com/DQmWaC4RnrX7UGhheVPNfZ9PW7MhR1HZQWYBA71zyd4p8SW/caniuse-notifications-api.png) (图片来源:[caniuse - Notifications](https://caniuse.com/#search=Notifications)) 从图中可以看出,Web Notifications API 在 PC 平台上的支持度还是蛮高的。作为 Chrome 的忠实用户,我就不用担心了。在支持该特性的平台上,显示系统通知需要以下步骤: - 判断用户是否授权显示通知,若用户未授权则可以使用 `Notification.requestPermission` 方法来请求通知授权; - 使用 `Notification` 构造函数创建一个新通知。 虽然我是 Chrome 粉,但为了保证代码的健壮性,我们还是得判断当前平台是否支持 Web Notifications API,如果当前平台支持的话,我们可以获取 Notification 对象,此外通过该对象的 permission 属性,我们可以获取用户对通知消息的授权情况,具体代码如下: ```javascript function initNotification() { if (!('Notification' in window)) { alert('当前浏览器不支持通知!'); } else if (Notification.permission === 'denied') { console.log('用户拒绝通知权限!'); } else if (Notification.permission === 'granted') { console.log('用户允许通知权限!'); } } ``` 如果发现 Notification 对象的 permission 状态不等于 **'granted'**,我们可以在发送通知的时候,调用 Notification 对象的 requestPermission 方法请求用户授权,具体代码如下: ```javascript // 监听发送通知操作 document.querySelector('#notificationsBtn').addEventListener('click', () => { if(Notification.permission === 'granted') { createNotification(); } else { Notification.requestPermission(function(permission) { // 如果用户同意,就可以向他们发送通知 if (permission === "granted") { createNotification(); } }); } }); ``` 那么问题来了,有没有办法手动调整通知权限呢?答案是可以的,也许有些小伙伴有留意到 sitepoint 通知消息上有一个 **设置** 按钮,当然你也可以在 chrome 中输入以下地址: ``` chrome://settings/content/notifications ``` 进入消息通知的设置页面。接下来我们来了解一下 Notification 构造函数,该构造函数接收两个参数: - title(必选)—— 定义一个通知的标题,当它被触发时,它将显示在通知窗口的顶部。 - options(可选)—— 包含应用于通知的任何自定义配置选项,支持的主要配置项有: - dir:显示通知的方向; - lang:指定通知中所使用的语言; - body:表示通知的正文,将显示在标题下方; - tag:表示通知的一个识别标签; - icon:包含要在通知中显示的图标的 URL; - data:与通知相关联的任意数据。 刷完 Web Notifications API 相关的基础知识,我们开始来实战一下,即模仿 sitepoint 发送的通知消息。经过多次尝试,我们发现只要简单配置相关参数,我们的 "赝品" 就有模有样了,具体代码如下: ```javascript var notification = new Notification( "Introducing WhatFontIs is the Easiest Way to Identify Fonts Online", { body: "A free service to help you ...", icon: "https://dab1nmslvvntp.cloudfront.net/wp-content/uploads/2017/10/[email protected]", }); ``` 通知消息已经能够显示出来了,但是感觉还是缺少了点东西。现在让我们来回想一下,当你点击手机上的桌面通知消息,系统会自动唤醒对应的 APP,然后进入到对应的通知页面。是的,没错!目前我们还需要响应用户点击通知的操作。通过查阅 Web Notifications API 相关文档,我们发现可以为新建的通知对象绑定点击事件的处理器,具体代码如下: ```javascript notification.onclick = () => { window.open('https://www.sitepoint.com/finding-fonts-whatfontis/'); }; ``` 以上代码成功运行后,当用户点击上述通知时,会自动创建新的 Tab 页并进入对应的页面。除了 `onclick` 事件处理器之外,通知对象还支持以下事件: - onshow:当通知显示时被触发; - onerror:当通知遇到错误时被触发; - onclose:当用户关闭通知时被触发。 下面我们来总结一下已使用过的属性: ![notification-detail.png](https://steemitimages.com/DQmVCbcMXPWkJ5Cr34iTQ8VPYRAPHvv3ptJUGucyW5PbVrk/notification-detail.png) **需要注意的是图中浏览器图标和当前域名是系统默认显示的**。 最后还有一个问题需要说明一下,如果用户在首次请求通知授权或者在通知设置页面中,禁止对当前域名的通知授权。**那么再次调用 Notification.requestPermission 方法,重新发起授权请求是无效的**。针对这个问题,我们可以引导用户重新启用通知权限,具体如下图所示: ![reset-notification-permission.png](https://steemitimages.com/DQmNudNPdUHqgDyMeq29yUPAXwwwU6JntNRdZ1z5Gyw1zke/reset-notification-permission.png) (Chrome 版本信息: 63.0.3239.132(正式版本) (64 位)) 本文通过模仿 [sitepoint](https://www.sitepoint.com/) 的消息通知,简单介绍了 Web Notifications API 相关的一些基础知识。完整的示例源码,已放到 [Gist](https://gist.github.com/semlinker/ddd190ad269c0866bbd2e35b4d4009a7) 上,有兴趣的小伙伴可以参考一下。下一篇文章,我们将介绍 Push API。刚开始学习PWA,以上内容有误之处,请小伙伴们多多指教。 ### 参考资源 - [MDN - Notification](https://developer.mozilla.org/zh-CN/docs/Web/API/Notification)
json metadata{"tags":["cn-programming","pwa","cn"],"image":["https://steemitimages.com/DQmZ2hkDxr5t3qdLaf3qvPEgLQd9q2U3Cn2v1dJjKGZTNHh/web-notifications-api.png","https://steemitimages.com/DQmfGKpZGpeap5FEuG7puqtFTCMcB9nWSfZxQewZBeZHy1M/sp-web-notifications.png","https://steemitimages.com/DQmWaC4RnrX7UGhheVPNfZ9PW7MhR1HZQWYBA71zyd4p8SW/caniuse-notifications-api.png","https://steemitimages.com/DQmVCbcMXPWkJ5Cr34iTQ8VPYRAPHvv3ptJUGucyW5PbVrk/notification-detail.png","https://steemitimages.com/DQmNudNPdUHqgDyMeq29yUPAXwwwU6JntNRdZ1z5Gyw1zke/reset-notification-permission.png"],"links":["https://developers.google.com/web/progressive-web-apps/","https://www.sitepoint.com/","https://caniuse.com/","https://caniuse.com/#search=Notifications","https://gist.github.com/semlinker/ddd190ad269c0866bbd2e35b4d4009a7","https://developer.mozilla.org/zh-CN/docs/Web/API/Notification"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkcn-programming
permlinkpwa-web-notifications-api
titlePWA 学习笔记之 Web Notifications API
Transaction InfoBlock #19141851/Trx 12271355bcecd03c8e87085f67affe4a5e9a3b24
View Raw JSON Data
{
  "block": 19141851,
  "op": [
    "comment",
    {
      "author": "semlinker",
      "body": "Web Notifications API 允许网页向最终用户显示系统通知,这些通知在顶级浏览器上下文窗口之外,因此即使用户已经切换标签页或移动到不同的应用程序,也可以正常显示。\n\n![web-notifications-api.png](https://steemitimages.com/DQmZ2hkDxr5t3qdLaf3qvPEgLQd9q2U3Cn2v1dJjKGZTNHh/web-notifications-api.png)\n\n(背景素材来源:[Google - progressive-web-apps](https://developers.google.com/web/progressive-web-apps/))\n\n说来也巧,在思考如何下笔时,刚好收到 [sitepoint](https://www.sitepoint.com/) 发来的通知。它竟然自己送上门来,那我就不客气了,直接拿它 \"开刀\"。\n\n![sp-web-notifications.png](https://steemitimages.com/DQmfGKpZGpeap5FEuG7puqtFTCMcB9nWSfZxQewZBeZHy1M/sp-web-notifications.png)\n\n(图片来源:[sitepoint](https://www.sitepoint.com/))\n\n初看起来,觉得挺简单的,但实际动手前却不知道如何下手,所以还是得乖乖地补一下 Web Notifications API 相关的基础知识。撸新的 API 前,直觉告诉我,还是得先了解一下其兼容性,这个任务当然还是交给我们的 [caniuse](https://caniuse.com/) 啦。写本文时,Web Notifications API 的兼容性如下图所示:\n\n![caniuse-notifications-api.png](https://steemitimages.com/DQmWaC4RnrX7UGhheVPNfZ9PW7MhR1HZQWYBA71zyd4p8SW/caniuse-notifications-api.png)\n\n(图片来源:[caniuse - Notifications](https://caniuse.com/#search=Notifications))\n\n从图中可以看出,Web Notifications API 在 PC 平台上的支持度还是蛮高的。作为 Chrome 的忠实用户,我就不用担心了。在支持该特性的平台上,显示系统通知需要以下步骤:\n\n- 判断用户是否授权显示通知,若用户未授权则可以使用 `Notification.requestPermission` 方法来请求通知授权;\n- 使用 `Notification` 构造函数创建一个新通知。\n\n虽然我是 Chrome 粉,但为了保证代码的健壮性,我们还是得判断当前平台是否支持 Web Notifications API,如果当前平台支持的话,我们可以获取 Notification 对象,此外通过该对象的 permission 属性,我们可以获取用户对通知消息的授权情况,具体代码如下:\n\n```javascript\nfunction initNotification() {\n    if (!('Notification' in window)) {\n      alert('当前浏览器不支持通知!');\n    } else if (Notification.permission === 'denied') {\n      console.log('用户拒绝通知权限!');\n    } else if (Notification.permission === 'granted') {\n      console.log('用户允许通知权限!');\n    }\n}\n```\n\n如果发现 Notification 对象的 permission 状态不等于 **'granted'**,我们可以在发送通知的时候,调用 Notification 对象的 requestPermission 方法请求用户授权,具体代码如下:\n\n```javascript\n// 监听发送通知操作\ndocument.querySelector('#notificationsBtn').addEventListener('click', () => {\n  if(Notification.permission === 'granted') {\n       createNotification();\n  } else {\n       Notification.requestPermission(function(permission) {\n          // 如果用户同意,就可以向他们发送通知\n          if (permission === \"granted\") {\n             createNotification();\n          }\n       });\n  }\n});\n```\n\n那么问题来了,有没有办法手动调整通知权限呢?答案是可以的,也许有些小伙伴有留意到 sitepoint 通知消息上有一个 **设置** 按钮,当然你也可以在 chrome 中输入以下地址:\n\n```\nchrome://settings/content/notifications\n```\n\n进入消息通知的设置页面。接下来我们来了解一下 Notification 构造函数,该构造函数接收两个参数:\n\n- title(必选)—— 定义一个通知的标题,当它被触发时,它将显示在通知窗口的顶部。\n- options(可选)—— 包含应用于通知的任何自定义配置选项,支持的主要配置项有:\n  - dir:显示通知的方向;\n  - lang:指定通知中所使用的语言;\n  - body:表示通知的正文,将显示在标题下方;\n  - tag:表示通知的一个识别标签;\n  - icon:包含要在通知中显示的图标的 URL;\n  - data:与通知相关联的任意数据。\n\n刷完 Web Notifications API 相关的基础知识,我们开始来实战一下,即模仿 sitepoint 发送的通知消息。经过多次尝试,我们发现只要简单配置相关参数,我们的 \"赝品\" 就有模有样了,具体代码如下:\n\n```javascript\nvar notification = new Notification(\n  \"Introducing WhatFontIs is the Easiest Way to Identify Fonts Online\",\n   {\n      body: \"A free service to help you ...\",\n      icon: \"https://dab1nmslvvntp.cloudfront.net/wp-content/uploads/2017/10/[email protected]\",\n});\n```\n\n通知消息已经能够显示出来了,但是感觉还是缺少了点东西。现在让我们来回想一下,当你点击手机上的桌面通知消息,系统会自动唤醒对应的 APP,然后进入到对应的通知页面。是的,没错!目前我们还需要响应用户点击通知的操作。通过查阅  Web Notifications API 相关文档,我们发现可以为新建的通知对象绑定点击事件的处理器,具体代码如下:\n\n```javascript\nnotification.onclick = () => {\n   window.open('https://www.sitepoint.com/finding-fonts-whatfontis/');\n};\n```\n\n以上代码成功运行后,当用户点击上述通知时,会自动创建新的 Tab 页并进入对应的页面。除了 `onclick` 事件处理器之外,通知对象还支持以下事件:\n\n- onshow:当通知显示时被触发;\n- onerror:当通知遇到错误时被触发;\n- onclose:当用户关闭通知时被触发。\n\n下面我们来总结一下已使用过的属性:\n\n![notification-detail.png](https://steemitimages.com/DQmVCbcMXPWkJ5Cr34iTQ8VPYRAPHvv3ptJUGucyW5PbVrk/notification-detail.png)\n\n**需要注意的是图中浏览器图标和当前域名是系统默认显示的**。\n\n最后还有一个问题需要说明一下,如果用户在首次请求通知授权或者在通知设置页面中,禁止对当前域名的通知授权。**那么再次调用 Notification.requestPermission 方法,重新发起授权请求是无效的**。针对这个问题,我们可以引导用户重新启用通知权限,具体如下图所示:\n\n![reset-notification-permission.png](https://steemitimages.com/DQmNudNPdUHqgDyMeq29yUPAXwwwU6JntNRdZ1z5Gyw1zke/reset-notification-permission.png)\n\n(Chrome 版本信息: 63.0.3239.132(正式版本) (64 位))\n\n本文通过模仿 [sitepoint](https://www.sitepoint.com/) 的消息通知,简单介绍了 Web Notifications API 相关的一些基础知识。完整的示例源码,已放到 [Gist](https://gist.github.com/semlinker/ddd190ad269c0866bbd2e35b4d4009a7) 上,有兴趣的小伙伴可以参考一下。下一篇文章,我们将介绍 Push API。刚开始学习PWA,以上内容有误之处,请小伙伴们多多指教。\n\n### 参考资源\n\n- [MDN - Notification](https://developer.mozilla.org/zh-CN/docs/Web/API/Notification)",
      "json_metadata": "{\"tags\":[\"cn-programming\",\"pwa\",\"cn\"],\"image\":[\"https://steemitimages.com/DQmZ2hkDxr5t3qdLaf3qvPEgLQd9q2U3Cn2v1dJjKGZTNHh/web-notifications-api.png\",\"https://steemitimages.com/DQmfGKpZGpeap5FEuG7puqtFTCMcB9nWSfZxQewZBeZHy1M/sp-web-notifications.png\",\"https://steemitimages.com/DQmWaC4RnrX7UGhheVPNfZ9PW7MhR1HZQWYBA71zyd4p8SW/caniuse-notifications-api.png\",\"https://steemitimages.com/DQmVCbcMXPWkJ5Cr34iTQ8VPYRAPHvv3ptJUGucyW5PbVrk/notification-detail.png\",\"https://steemitimages.com/DQmNudNPdUHqgDyMeq29yUPAXwwwU6JntNRdZ1z5Gyw1zke/reset-notification-permission.png\"],\"links\":[\"https://developers.google.com/web/progressive-web-apps/\",\"https://www.sitepoint.com/\",\"https://caniuse.com/\",\"https://caniuse.com/#search=Notifications\",\"https://gist.github.com/semlinker/ddd190ad269c0866bbd2e35b4d4009a7\",\"https://developer.mozilla.org/zh-CN/docs/Web/API/Notification\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "cn-programming",
      "permlink": "pwa-web-notifications-api",
      "title": "PWA 学习笔记之 Web Notifications API"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-20T11:23:57",
  "trx_id": "12271355bcecd03c8e87085f67affe4a5e9a3b24",
  "trx_in_block": 19,
  "virtual_op": 0
}
2018/01/20 10:57:12
authorsemlinker
body@@ -5638,11 +5638,11 @@ %E5%AD%98%E6%8E%A7%E5%88%B6%E3%80%82 -%E4%B8%8B%E4%B8%80%E7%AF%87 +%E5%90%8E%E9%9D%A2%E7%9A%84 %E6%96%87%E7%AB%A0%E6%88%91%E4%BB%AC
json metadata{"tags":["cn-programming","pwa","cn"],"image":["https://steemitimages.com/DQmP1EF4C18okZh85mv8MpR9M8CzJ6W6X4WkbWF6SXTNVDj/sws-cache-control.png","https://steemitimages.com/DQmQDgeFw2e5DVoK29v2y7t2F5jeL9zPcaghR2a2F8cMVDh/sw-cache-v1.jpg","https://steemitimages.com/DQmZ1BxVxdZqS1EAdCPK7fuUz1ey5ZwNwKAi8bruNDRawxi/resource-from-sw.png","https://steemitimages.com/DQmdYavQJHrv3ENtxiWERKV5oP6oTu84GQ2b45igYwwNSfc/resource-request-fail.png"],"links":["https://steemit.com/cn-programming/@semlinker/pwa-service-workers","https://developers.google.com/web/progressive-web-apps/","https://steemit.com/cn-programming/@semlinker/pwa-cachestorage-api","https://developer.mozilla.org/zh-CN/docs/Web/API/Response/Response"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkcn-programming
permlinkpwa-service-workers-cache-control
titlePWA 学习笔记之 Service Workers Cache Control
Transaction InfoBlock #19141317/Trx 8dfed72ee320d5e04272219016bf89bc1ac4dbbb
View Raw JSON Data
{
  "block": 19141317,
  "op": [
    "comment",
    {
      "author": "semlinker",
      "body": "@@ -5638,11 +5638,11 @@\n %E5%AD%98%E6%8E%A7%E5%88%B6%E3%80%82\n-%E4%B8%8B%E4%B8%80%E7%AF%87\n+%E5%90%8E%E9%9D%A2%E7%9A%84\n %E6%96%87%E7%AB%A0%E6%88%91%E4%BB%AC\n",
      "json_metadata": "{\"tags\":[\"cn-programming\",\"pwa\",\"cn\"],\"image\":[\"https://steemitimages.com/DQmP1EF4C18okZh85mv8MpR9M8CzJ6W6X4WkbWF6SXTNVDj/sws-cache-control.png\",\"https://steemitimages.com/DQmQDgeFw2e5DVoK29v2y7t2F5jeL9zPcaghR2a2F8cMVDh/sw-cache-v1.jpg\",\"https://steemitimages.com/DQmZ1BxVxdZqS1EAdCPK7fuUz1ey5ZwNwKAi8bruNDRawxi/resource-from-sw.png\",\"https://steemitimages.com/DQmdYavQJHrv3ENtxiWERKV5oP6oTu84GQ2b45igYwwNSfc/resource-request-fail.png\"],\"links\":[\"https://steemit.com/cn-programming/@semlinker/pwa-service-workers\",\"https://developers.google.com/web/progressive-web-apps/\",\"https://steemit.com/cn-programming/@semlinker/pwa-cachestorage-api\",\"https://developer.mozilla.org/zh-CN/docs/Web/API/Response/Response\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "cn-programming",
      "permlink": "pwa-service-workers-cache-control",
      "title": "PWA 学习笔记之 Service Workers Cache Control"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-20T10:57:12",
  "trx_id": "8dfed72ee320d5e04272219016bf89bc1ac4dbbb",
  "trx_in_block": 6,
  "virtual_op": 0
}
2018/01/19 09:21:36
authorsemlinker
body@@ -341,16 +341,115 @@ l.png)%0A%0A +(%E8%83%8C%E6%99%AF%E7%B4%A0%E6%9D%90%E6%9D%A5%E6%BA%90%EF%BC%9A%5BGoogle - progressive-web-apps%5D(https://developers.google.com/web/progressive-web-apps/))%0A%0A ### fetc
json metadata{"tags":["cn-programming","pwa","cn"],"image":["https://steemitimages.com/DQmP1EF4C18okZh85mv8MpR9M8CzJ6W6X4WkbWF6SXTNVDj/sws-cache-control.png","https://steemitimages.com/DQmQDgeFw2e5DVoK29v2y7t2F5jeL9zPcaghR2a2F8cMVDh/sw-cache-v1.jpg","https://steemitimages.com/DQmZ1BxVxdZqS1EAdCPK7fuUz1ey5ZwNwKAi8bruNDRawxi/resource-from-sw.png","https://steemitimages.com/DQmdYavQJHrv3ENtxiWERKV5oP6oTu84GQ2b45igYwwNSfc/resource-request-fail.png"],"links":["https://steemit.com/cn-programming/@semlinker/pwa-service-workers","https://developers.google.com/web/progressive-web-apps/","https://steemit.com/cn-programming/@semlinker/pwa-cachestorage-api","https://developer.mozilla.org/zh-CN/docs/Web/API/Response/Response"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkcn-programming
permlinkpwa-service-workers-cache-control
titlePWA 学习笔记之 Service Workers Cache Control
Transaction InfoBlock #19110634/Trx 36f988d49cda99ba210dfd5679be366e8b02d951
View Raw JSON Data
{
  "block": 19110634,
  "op": [
    "comment",
    {
      "author": "semlinker",
      "body": "@@ -341,16 +341,115 @@\n l.png)%0A%0A\n+(%E8%83%8C%E6%99%AF%E7%B4%A0%E6%9D%90%E6%9D%A5%E6%BA%90%EF%BC%9A%5BGoogle - progressive-web-apps%5D(https://developers.google.com/web/progressive-web-apps/))%0A%0A\n ### fetc\n",
      "json_metadata": "{\"tags\":[\"cn-programming\",\"pwa\",\"cn\"],\"image\":[\"https://steemitimages.com/DQmP1EF4C18okZh85mv8MpR9M8CzJ6W6X4WkbWF6SXTNVDj/sws-cache-control.png\",\"https://steemitimages.com/DQmQDgeFw2e5DVoK29v2y7t2F5jeL9zPcaghR2a2F8cMVDh/sw-cache-v1.jpg\",\"https://steemitimages.com/DQmZ1BxVxdZqS1EAdCPK7fuUz1ey5ZwNwKAi8bruNDRawxi/resource-from-sw.png\",\"https://steemitimages.com/DQmdYavQJHrv3ENtxiWERKV5oP6oTu84GQ2b45igYwwNSfc/resource-request-fail.png\"],\"links\":[\"https://steemit.com/cn-programming/@semlinker/pwa-service-workers\",\"https://developers.google.com/web/progressive-web-apps/\",\"https://steemit.com/cn-programming/@semlinker/pwa-cachestorage-api\",\"https://developer.mozilla.org/zh-CN/docs/Web/API/Response/Response\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "cn-programming",
      "permlink": "pwa-service-workers-cache-control",
      "title": "PWA 学习笔记之 Service Workers Cache Control"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-19T09:21:36",
  "trx_id": "36f988d49cda99ba210dfd5679be366e8b02d951",
  "trx_in_block": 4,
  "virtual_op": 0
}
2018/01/19 09:16:21
authorsemlinker
permlinkpwa-service-workers-cache-control
voterboopathy
weight10000 (100.00%)
Transaction InfoBlock #19110529/Trx 000b75dd54ff5bb11675ea85edf0ca38f60cc678
View Raw JSON Data
{
  "block": 19110529,
  "op": [
    "vote",
    {
      "author": "semlinker",
      "permlink": "pwa-service-workers-cache-control",
      "voter": "boopathy",
      "weight": 10000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-19T09:16:21",
  "trx_id": "000b75dd54ff5bb11675ea85edf0ca38f60cc678",
  "trx_in_block": 6,
  "virtual_op": 0
}
2018/01/19 09:16:06
authorsemlinker
body通过[PWA 学习笔记之 Service Workers](https://steemit.com/cn-programming/@semlinker/pwa-service-workers)这篇文章,我们了解了如何使用、调试、更新 Service Worker 及 Service Worker 生命周期相关知识。接下来本文将介绍如何利用 fetch API、CacheStorage API 及 Service Worker 实现缓存控制。 ![sws-cache-control.png](https://steemitimages.com/DQmP1EF4C18okZh85mv8MpR9M8CzJ6W6X4WkbWF6SXTNVDj/sws-cache-control.png) ### fetch 事件及自定义响应 在你使用缓存前,你必须能够拦截网络请求。强大的 Service Worker 为我们提供了这种能力,在 Service Worker 作用域内的每个网络请求,将会触发 fetch 事件: ```javascript self.addEventListener('fetch', (event) => { event.respondWith(fetch(event.request)); }); ``` 以上代码我们只是实现简单的请求代理,实际上并没有多大用途,其实我们是可以自定义响应对象,即通过 fetch API 定义的 Response 接口,创建响应对象,使用的语法如下: ```javascript let myResponse = new Response(body, init); ``` **参数说明**: - body(可选)—— 定义 response 中 body 内容,支持以下数据类型: - Blob - BufferSource - FormData - URLSearchParams - USVString - init(可选)—— 用于配置响应对象,支持以下属性: - status:响应的状态码,如 200 - statusText:与状态码关联的状态信息,如 OK - headers:响应头部对象 **使用示例**: ```javascript var myBlob = new Blob(); var init = { "status" : 200 , "statusText" : "Awesome!" }; var myResponse = new Response(myBlob,init); ``` 光写不练假把式,我们立马实践一下,手动更新 service-worker.js 文件: ```javascript self.addEventListener('install', (event) => { self.skipWaiting(); console.log('Update service worker installed', event); }); self.addEventListener('activate', (event) => { console.log('Update service worker activated', event); }); // 以下是新增的内容 self.addEventListener('fetch', (event) => { event.respondWith(new Response('My name is semlinker!')); }); ``` 更新完保存文件,然后在浏览器中访问 index.html 文件,此时你会在页面中看到以下内容: ``` My name is semlinker! ``` ### CacheStorage API 缓存是我们的好朋友,利用缓存我们甚至可以在离线状态下,使得 App 仍然可以使用。接下来我们继续更新 service-worker.js 文件,在 install 事件处理函数中,我们利用 CacheStorage API 对特定的资源进行缓存: ```javascript self.addEventListener('install', (event) => { self.skipWaiting(); if ('caches' in self) { event.waitUntil( caches.open('v1').then((cache) => { return cache.addAll([ './index.html', './script.js', './sw-in-action.png' ]); }) ); } console.log('Update service worker installed', event); }); // 注释掉自定义响应对象 self.addEventListener('fetch', (event) => { // event.respondWith(new Response('My name is semlinker!')); }); ``` 在 install 事件处理函数中,我们先判断当前浏览器是否支持 CacheStorage API,若当前浏览器支持该 API 的话,我们也可以通过 `window.caches` 访问 CacheStorage 对象。然后我们使用 `event.waitUntil` 方法让 Service Worker 处于 installing 阶段,直到设定的任务完成。这里需要注意的是,event.waitUntil 方法的参数类型必须为 Promise。 最后,我们调用 `caches.open('v1')` 方法来获取 v1 版本的缓存对象(若不存在,则会自动创建),进而通过调用缓存对象的 addAll 方法,缓存对应资源。 为了能够更直观的感受缓存特性,我们新增了一张图片资源。这时,我们需要注释掉 fetch 事件处理器中,自定义响应的代码。除此之外,我们也需要更新一下 index.html 文件,新增以下 img 标签: ```html <!-- <img src="sw-in-action.png"> --> ``` 万事俱备只欠东风,接下来重新刷新一下浏览器,不出所料的话,你将会看到一张图片。难道这样就结束了?当然不是,我们还没检查已设置的资源,是否被成功缓存。还是老样子,打开开发者工具,切换到 Application Tab 页,不过这次我们打开的是 Cache 菜单下的 CacheStorage 子菜单,具体内容如下图所示: ![sw-cache-v1.jpg](https://steemitimages.com/DQmQDgeFw2e5DVoK29v2y7t2F5jeL9zPcaghR2a2F8cMVDh/sw-cache-v1.jpg) 通过上图,可以发现我们设置的资源已经被成功缓存了。那么,接下来的事情就是应该如何利用缓存。不知道小伙伴们,是否还记得[PWA 学习笔记之 CacheStorage API](https://steemit.com/cn-programming/@semlinker/pwa-cachestorage-api)这篇文章中介绍过的 match 方法,**该方法返回一个 Promise 对象,用于判断给定的请求对象是否已被缓存。若匹配则返回已缓存的对象**。下面,我来继续更新 service-worker.js 文件,这里我们只需更新 fetch 事件处理器: ```javascript self.addEventListener('fetch', (event) => { event.respondWith( caches.match(event.request) ); }); ``` 重新保存 service-worker.js 文件,在成功激活新的 Service Worker 后,我们先切换到 Network Tab 页,然后再次刷新一下浏览器。具体的内容如下图所示: ![resource-from-sw.png](https://steemitimages.com/DQmZ1BxVxdZqS1EAdCPK7fuUz1ey5ZwNwKAi8bruNDRawxi/resource-from-sw.png) 从图中,我们可以看出当刷新当前页面时,Service Worker 直接为我们返回了之前已缓存的资源。另外,感兴趣的小伙伴,你也可以把网络状态设置为 Offline,或者进入 Application Tab 页,把 Cache Storage 中 v1 的缓存删掉,然后再刷新当前页面,看一下页面的显示情况。 其实 fetch 事件处理器的代码存在一个问题,假如我们哪天更新了 index.html 文件,比如再次新增一个 img 标签,它引用了新的图片资源,但并没有把新的图片资源保存到缓存对象中,这时会出现什么问题呢?我们立马来验证一下,具体流程如下: - 复制已有的 sw-in-action.png 文件,重命名为 sw-in-action-1.png; - 更新 index.html 文件,添加新的 img 标签并设置其 src 地址(引用刚创建的 sw-in-action-1.png 文件)。 保存文件,刷新当前页面,再次观察 Network Tab 页的内容,具体如下图所示: ![resource-request-fail.png](https://steemitimages.com/DQmdYavQJHrv3ENtxiWERKV5oP6oTu84GQ2b45igYwwNSfc/resource-request-fail.png) 图中我们发现已缓存的资源,能够正常返回,但由于我们没有把 sw-in-action-1.png 文件,添加到缓存中,使得该资源的请求,缓存匹配失败,最终导致 sw-in-action-1.png 该文件无法在页面中正常显示 。 那么如何解决这个问题呢?最简单的方案就是把 sw-in-action-1.png 文件添加到 cache.addAll 方法的数组中。这样虽然可以解决问题,但有没有更好的方案呢?**理想的情况下,我们优先从缓存中获取对应的资源,若缓存中不存在对应的资源,且当前网络是可用的情况下,我们可以在无法获取缓存的时候,发起网络请求,获取对应的资源**。按照以上的分析思路,我们再来更新一下 service-worker.js 文件,具体如下: ```javascript self.addEventListener('fetch', (event) => { event.respondWith( caches.match(event.request).then((response) => { // 若缓存命中,则直接返回缓存对象,否则通过fetch API从网络获取 return response || fetch(event.request); }) ); }); ``` 使用上面的代码,我们解决了刚才遇到的问题。那么上述的代码,还可以优化么?答案是可以的,我们可以把从网络获取的资源,添加到缓存对象中,以保证离线状态下,仍可以使用。要实现该功能,还是利用我们之前学过的 CacheStorage API,具体实现代码如下: ```javascript self.addEventListener('fetch', (event) => { event.respondWith( caches.match(event.request).then((response) => { return response || fetch(event.request).then((response) => { return caches.open('v1').then((cache) => { cache.put(event.request, response.clone()); return response; }); }); }) ); }); ``` 通过这篇文章我们把之前所学的知识,如 fetch API、CacheStorage API 及 Service Worker 等知识综合应用起来,简单实现了缓存控制。下一篇文章我们将介绍不同的缓存策略及如何更新缓存。刚开始学习 PWA,以上内容有误之处,请小伙伴们多多指教。 ### 参考资源 - [MDN - Response](https://developer.mozilla.org/zh-CN/docs/Web/API/Response/Response)
json metadata{"tags":["cn-programming","pwa","cn"],"image":["https://steemitimages.com/DQmP1EF4C18okZh85mv8MpR9M8CzJ6W6X4WkbWF6SXTNVDj/sws-cache-control.png","https://steemitimages.com/DQmQDgeFw2e5DVoK29v2y7t2F5jeL9zPcaghR2a2F8cMVDh/sw-cache-v1.jpg","https://steemitimages.com/DQmZ1BxVxdZqS1EAdCPK7fuUz1ey5ZwNwKAi8bruNDRawxi/resource-from-sw.png","https://steemitimages.com/DQmdYavQJHrv3ENtxiWERKV5oP6oTu84GQ2b45igYwwNSfc/resource-request-fail.png"],"links":["https://steemit.com/cn-programming/@semlinker/pwa-service-workers","https://steemit.com/cn-programming/@semlinker/pwa-cachestorage-api","https://developer.mozilla.org/zh-CN/docs/Web/API/Response/Response"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkcn-programming
permlinkpwa-service-workers-cache-control
titlePWA 学习笔记之 Service Workers Cache Control
Transaction InfoBlock #19110524/Trx 8ab83c90070d080510d731720dcf07c2b9c480ff
View Raw JSON Data
{
  "block": 19110524,
  "op": [
    "comment",
    {
      "author": "semlinker",
      "body": "通过[PWA 学习笔记之 Service Workers](https://steemit.com/cn-programming/@semlinker/pwa-service-workers)这篇文章,我们了解了如何使用、调试、更新 Service  Worker 及 Service Worker 生命周期相关知识。接下来本文将介绍如何利用 fetch API、CacheStorage API 及 Service Worker 实现缓存控制。\n\n![sws-cache-control.png](https://steemitimages.com/DQmP1EF4C18okZh85mv8MpR9M8CzJ6W6X4WkbWF6SXTNVDj/sws-cache-control.png)\n\n### fetch 事件及自定义响应\n\n在你使用缓存前,你必须能够拦截网络请求。强大的 Service Worker 为我们提供了这种能力,在 Service Worker 作用域内的每个网络请求,将会触发 fetch 事件:\n\n```javascript\nself.addEventListener('fetch', (event) => {\n  event.respondWith(fetch(event.request));\n});\n```\n\n以上代码我们只是实现简单的请求代理,实际上并没有多大用途,其实我们是可以自定义响应对象,即通过 fetch API 定义的 Response 接口,创建响应对象,使用的语法如下:\n\n```javascript\nlet myResponse = new Response(body, init);\n```\n\n **参数说明**:\n\n- body(可选)—— 定义 response 中 body 内容,支持以下数据类型:\n  - Blob\n  - BufferSource\n  - FormData\n  - URLSearchParams\n  - USVString\n- init(可选)—— 用于配置响应对象,支持以下属性:\n  - status:响应的状态码,如 200\n  - statusText:与状态码关联的状态信息,如 OK\n  - headers:响应头部对象\n\n**使用示例**:\n\n```javascript\nvar myBlob = new Blob();\nvar init = { \"status\" : 200 , \"statusText\" : \"Awesome!\" };\nvar myResponse = new Response(myBlob,init);\n```\n\n光写不练假把式,我们立马实践一下,手动更新 service-worker.js 文件:\n\n```javascript\nself.addEventListener('install', (event) => {\n    self.skipWaiting();\n    console.log('Update service worker installed', event);\n});\n\nself.addEventListener('activate', (event) => {\n    console.log('Update service worker activated', event);\n});\n\n// 以下是新增的内容\nself.addEventListener('fetch', (event) => {\n    event.respondWith(new Response('My name is semlinker!'));\n});\n```\n\n更新完保存文件,然后在浏览器中访问 index.html 文件,此时你会在页面中看到以下内容:\n\n```\nMy name is semlinker!\n```\n\n### CacheStorage API\n\n缓存是我们的好朋友,利用缓存我们甚至可以在离线状态下,使得 App 仍然可以使用。接下来我们继续更新 service-worker.js 文件,在 install 事件处理函数中,我们利用 CacheStorage API 对特定的资源进行缓存:\n\n```javascript\nself.addEventListener('install', (event) => {\n    self.skipWaiting();\n    if ('caches' in self) {\n        event.waitUntil(\n            caches.open('v1').then((cache) => {\n                return cache.addAll([\n                    './index.html',\n                    './script.js',\n                    './sw-in-action.png'\n                ]);\n            })\n        );\n    }\n    console.log('Update service worker installed', event);\n});\n\n// 注释掉自定义响应对象\nself.addEventListener('fetch', (event) => {\n    // event.respondWith(new Response('My name is semlinker!'));\n});\n```\n\n在 install 事件处理函数中,我们先判断当前浏览器是否支持 CacheStorage API,若当前浏览器支持该 API 的话,我们也可以通过 `window.caches` 访问 CacheStorage 对象。然后我们使用 `event.waitUntil` 方法让 Service  Worker 处于 installing 阶段,直到设定的任务完成。这里需要注意的是,event.waitUntil 方法的参数类型必须为 Promise。\n\n最后,我们调用 `caches.open('v1')` 方法来获取 v1 版本的缓存对象(若不存在,则会自动创建),进而通过调用缓存对象的 addAll 方法,缓存对应资源。\n\n为了能够更直观的感受缓存特性,我们新增了一张图片资源。这时,我们需要注释掉 fetch 事件处理器中,自定义响应的代码。除此之外,我们也需要更新一下 index.html 文件,新增以下 img 标签:\n\n```html\n <!-- <img src=\"sw-in-action.png\"> -->\n```\n\n万事俱备只欠东风,接下来重新刷新一下浏览器,不出所料的话,你将会看到一张图片。难道这样就结束了?当然不是,我们还没检查已设置的资源,是否被成功缓存。还是老样子,打开开发者工具,切换到 Application Tab 页,不过这次我们打开的是 Cache 菜单下的 CacheStorage 子菜单,具体内容如下图所示:\n\n![sw-cache-v1.jpg](https://steemitimages.com/DQmQDgeFw2e5DVoK29v2y7t2F5jeL9zPcaghR2a2F8cMVDh/sw-cache-v1.jpg)\n\n通过上图,可以发现我们设置的资源已经被成功缓存了。那么,接下来的事情就是应该如何利用缓存。不知道小伙伴们,是否还记得[PWA 学习笔记之 CacheStorage API](https://steemit.com/cn-programming/@semlinker/pwa-cachestorage-api)这篇文章中介绍过的 match 方法,**该方法返回一个 Promise 对象,用于判断给定的请求对象是否已被缓存。若匹配则返回已缓存的对象**。下面,我来继续更新 service-worker.js 文件,这里我们只需更新 fetch 事件处理器:\n\n```javascript\nself.addEventListener('fetch', (event) => {\n    event.respondWith(\n        caches.match(event.request)\n    );\n});\n```\n\n重新保存 service-worker.js 文件,在成功激活新的 Service Worker 后,我们先切换到 Network Tab 页,然后再次刷新一下浏览器。具体的内容如下图所示:\n\n![resource-from-sw.png](https://steemitimages.com/DQmZ1BxVxdZqS1EAdCPK7fuUz1ey5ZwNwKAi8bruNDRawxi/resource-from-sw.png)\n\n从图中,我们可以看出当刷新当前页面时,Service Worker 直接为我们返回了之前已缓存的资源。另外,感兴趣的小伙伴,你也可以把网络状态设置为 Offline,或者进入 Application Tab 页,把 Cache Storage 中 v1 的缓存删掉,然后再刷新当前页面,看一下页面的显示情况。\n\n其实 fetch 事件处理器的代码存在一个问题,假如我们哪天更新了 index.html 文件,比如再次新增一个 img 标签,它引用了新的图片资源,但并没有把新的图片资源保存到缓存对象中,这时会出现什么问题呢?我们立马来验证一下,具体流程如下:\n\n- 复制已有的 sw-in-action.png 文件,重命名为 sw-in-action-1.png;\n- 更新 index.html 文件,添加新的 img 标签并设置其 src 地址(引用刚创建的 sw-in-action-1.png 文件)。\n\n保存文件,刷新当前页面,再次观察 Network Tab 页的内容,具体如下图所示:\n\n![resource-request-fail.png](https://steemitimages.com/DQmdYavQJHrv3ENtxiWERKV5oP6oTu84GQ2b45igYwwNSfc/resource-request-fail.png)\n\n图中我们发现已缓存的资源,能够正常返回,但由于我们没有把 sw-in-action-1.png 文件,添加到缓存中,使得该资源的请求,缓存匹配失败,最终导致 sw-in-action-1.png 该文件无法在页面中正常显示 。\n\n那么如何解决这个问题呢?最简单的方案就是把 sw-in-action-1.png 文件添加到 cache.addAll 方法的数组中。这样虽然可以解决问题,但有没有更好的方案呢?**理想的情况下,我们优先从缓存中获取对应的资源,若缓存中不存在对应的资源,且当前网络是可用的情况下,我们可以在无法获取缓存的时候,发起网络请求,获取对应的资源**。按照以上的分析思路,我们再来更新一下 service-worker.js 文件,具体如下:\n\n```javascript\nself.addEventListener('fetch', (event) => {\n  event.respondWith(\n    caches.match(event.request).then((response) => {\n    // 若缓存命中,则直接返回缓存对象,否则通过fetch API从网络获取\n      return response || fetch(event.request);\n     })\n  );\n});\n```\n\n使用上面的代码,我们解决了刚才遇到的问题。那么上述的代码,还可以优化么?答案是可以的,我们可以把从网络获取的资源,添加到缓存对象中,以保证离线状态下,仍可以使用。要实现该功能,还是利用我们之前学过的 CacheStorage API,具体实现代码如下:\n\n```javascript\nself.addEventListener('fetch', (event) => {\n    event.respondWith(\n        caches.match(event.request).then((response) => {\n            return response || fetch(event.request).then((response) => {\n                return caches.open('v1').then((cache) => {\n                    cache.put(event.request, response.clone());\n                    return response;\n                });\n            });\n        })\n    );\n});\n```\n\n通过这篇文章我们把之前所学的知识,如 fetch API、CacheStorage API 及 Service Worker 等知识综合应用起来,简单实现了缓存控制。下一篇文章我们将介绍不同的缓存策略及如何更新缓存。刚开始学习 PWA,以上内容有误之处,请小伙伴们多多指教。\n\n### 参考资源\n\n- [MDN - Response](https://developer.mozilla.org/zh-CN/docs/Web/API/Response/Response)",
      "json_metadata": "{\"tags\":[\"cn-programming\",\"pwa\",\"cn\"],\"image\":[\"https://steemitimages.com/DQmP1EF4C18okZh85mv8MpR9M8CzJ6W6X4WkbWF6SXTNVDj/sws-cache-control.png\",\"https://steemitimages.com/DQmQDgeFw2e5DVoK29v2y7t2F5jeL9zPcaghR2a2F8cMVDh/sw-cache-v1.jpg\",\"https://steemitimages.com/DQmZ1BxVxdZqS1EAdCPK7fuUz1ey5ZwNwKAi8bruNDRawxi/resource-from-sw.png\",\"https://steemitimages.com/DQmdYavQJHrv3ENtxiWERKV5oP6oTu84GQ2b45igYwwNSfc/resource-request-fail.png\"],\"links\":[\"https://steemit.com/cn-programming/@semlinker/pwa-service-workers\",\"https://steemit.com/cn-programming/@semlinker/pwa-cachestorage-api\",\"https://developer.mozilla.org/zh-CN/docs/Web/API/Response/Response\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "cn-programming",
      "permlink": "pwa-service-workers-cache-control",
      "title": "PWA 学习笔记之 Service Workers Cache Control"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-19T09:16:06",
  "trx_id": "8ab83c90070d080510d731720dcf07c2b9c480ff",
  "trx_in_block": 3,
  "virtual_op": 0
}
semlinkerpublished a new post: pwa-service-workers
2018/01/19 08:25:06
authorsemlinker
body@@ -5465,18 +5465,16 @@ orker %E5%AE%9E%E7%8E%B0 -%E9%A1%B5%E9%9D%A2 %E7%BC%93%E5%AD%98%E6%8E%A7%E5%88%B6%EF%BC%8C%E5%88%9A%E5%BC%80%E5%A7%8B
json metadata{"tags":["cn-programming","pwa","cn"],"image":["https://steemitimages.com/DQmRUzuKqD9yraRvRGWtePCcc4tvKssCVcxpLoxziPr4fsf/service-worker.png","https://steemitimages.com/DQmcR6xAHuAHyLKKceEzedXei8HvhwhFBvKPvTE4MWDVCiF/sw-registration.jpg","https://steemitimages.com/DQmX2Ko7BUQkmYvvBYdt36PKhfQYEZGFTNC6GCa41FCfHwb/dev-sw-tab.png","https://steemitimages.com/DQmVvPkb6Dh6HypAEfcJY7m4daJLGqaFRvsb5SNMKBohocH/sw-update.jpg","https://steemitimages.com/DQmdQ9QLBDozkVi6wiFeewfqxm6KJrrUNrZ7H3re2ba9dat/sw-lifecycle.png"],"links":["https://developers.google.com/web/progressive-web-apps/","https://support.mozilla.org/zh-CN/kb/%E9%9A%90%E7%A7%81%E6%B5%8F%E8%A7%88","https://developers.google.com/web/fundamentals/primers/service-workers/?hl=zh-cn#_2","https://caniuse.com/#search=service%20worker","https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb?hl=zh-cn","https://developers.google.com/web/ilt/pwa/introduction-to-progressive-web-app-architectures","https://developer.mozilla.org/zh-CN/docs/Web/API/Service_Worker_API","https://developers.google.com/web/fundamentals/codelabs/debugging-service-workers/?hl=zh-cn"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkcn-programming
permlinkpwa-service-workers
titlePWA 学习笔记之 Service Workers
Transaction InfoBlock #19109505/Trx 6596d1e5d8ff89f07be165f05486e78e1669eaca
View Raw JSON Data
{
  "block": 19109505,
  "op": [
    "comment",
    {
      "author": "semlinker",
      "body": "@@ -5465,18 +5465,16 @@\n orker %E5%AE%9E%E7%8E%B0\n-%E9%A1%B5%E9%9D%A2\n %E7%BC%93%E5%AD%98%E6%8E%A7%E5%88%B6%EF%BC%8C%E5%88%9A%E5%BC%80%E5%A7%8B\n",
      "json_metadata": "{\"tags\":[\"cn-programming\",\"pwa\",\"cn\"],\"image\":[\"https://steemitimages.com/DQmRUzuKqD9yraRvRGWtePCcc4tvKssCVcxpLoxziPr4fsf/service-worker.png\",\"https://steemitimages.com/DQmcR6xAHuAHyLKKceEzedXei8HvhwhFBvKPvTE4MWDVCiF/sw-registration.jpg\",\"https://steemitimages.com/DQmX2Ko7BUQkmYvvBYdt36PKhfQYEZGFTNC6GCa41FCfHwb/dev-sw-tab.png\",\"https://steemitimages.com/DQmVvPkb6Dh6HypAEfcJY7m4daJLGqaFRvsb5SNMKBohocH/sw-update.jpg\",\"https://steemitimages.com/DQmdQ9QLBDozkVi6wiFeewfqxm6KJrrUNrZ7H3re2ba9dat/sw-lifecycle.png\"],\"links\":[\"https://developers.google.com/web/progressive-web-apps/\",\"https://support.mozilla.org/zh-CN/kb/%E9%9A%90%E7%A7%81%E6%B5%8F%E8%A7%88\",\"https://developers.google.com/web/fundamentals/primers/service-workers/?hl=zh-cn#_2\",\"https://caniuse.com/#search=service%20worker\",\"https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb?hl=zh-cn\",\"https://developers.google.com/web/ilt/pwa/introduction-to-progressive-web-app-architectures\",\"https://developer.mozilla.org/zh-CN/docs/Web/API/Service_Worker_API\",\"https://developers.google.com/web/fundamentals/codelabs/debugging-service-workers/?hl=zh-cn\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "cn-programming",
      "permlink": "pwa-service-workers",
      "title": "PWA 学习笔记之 Service Workers"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-19T08:25:06",
  "trx_id": "6596d1e5d8ff89f07be165f05486e78e1669eaca",
  "trx_in_block": 34,
  "virtual_op": 0
}
2018/01/18 16:17:54
authortumutanzi
permlink69vabx-steemit
votersemlinker
weight10000 (100.00%)
Transaction InfoBlock #19090164/Trx 04970f115a775fd01627c93aaa9136ae3fc4a658
View Raw JSON Data
{
  "block": 19090164,
  "op": [
    "vote",
    {
      "author": "tumutanzi",
      "permlink": "69vabx-steemit",
      "voter": "semlinker",
      "weight": 10000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-18T16:17:54",
  "trx_id": "04970f115a775fd01627c93aaa9136ae3fc4a658",
  "trx_in_block": 42,
  "virtual_op": 0
}
semlinkerupvoted (100.00%) @myfirst / steem
2018/01/18 16:08:57
authormyfirst
permlinksteem
votersemlinker
weight10000 (100.00%)
Transaction InfoBlock #19089986/Trx ca55364ff106dff8fbb430ba7fd9badb5dfcaf20
View Raw JSON Data
{
  "block": 19089986,
  "op": [
    "vote",
    {
      "author": "myfirst",
      "permlink": "steem",
      "voter": "semlinker",
      "weight": 10000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-18T16:08:57",
  "trx_id": "ca55364ff106dff8fbb430ba7fd9badb5dfcaf20",
  "trx_in_block": 53,
  "virtual_op": 0
}
semlinkerupvoted (100.00%) @tumutanzi / steemit
2018/01/18 16:00:06
authortumutanzi
permlinksteemit
votersemlinker
weight10000 (100.00%)
Transaction InfoBlock #19089809/Trx 3fc2396f2cbfb1cef257c33fbf1ff7b2de14089b
View Raw JSON Data
{
  "block": 19089809,
  "op": [
    "vote",
    {
      "author": "tumutanzi",
      "permlink": "steemit",
      "voter": "semlinker",
      "weight": 10000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-18T16:00:06",
  "trx_id": "3fc2396f2cbfb1cef257c33fbf1ff7b2de14089b",
  "trx_in_block": 41,
  "virtual_op": 0
}
2018/01/18 15:59:54
authorsemlinker
body果然之前发的文章就不能更改了,幸亏5天前的文章还有编辑按钮,看来以后发文章要认真点咯,后面也得抽空了解一下 Steemit 的运行机制,谢谢分享。
json metadata{"tags":["cn"],"app":"steemit/0.1"}
parent authortumutanzi
parent permlinkre-justyy-re-tumutanzi-steemit-20170706t203552487z
permlinkre-tumutanzi-re-justyy-re-tumutanzi-steemit-20180118t155952628z
title
Transaction InfoBlock #19089805/Trx a50941c361b7827fbe09618c1818b1b60d56f10d
View Raw JSON Data
{
  "block": 19089805,
  "op": [
    "comment",
    {
      "author": "semlinker",
      "body": "果然之前发的文章就不能更改了,幸亏5天前的文章还有编辑按钮,看来以后发文章要认真点咯,后面也得抽空了解一下 Steemit 的运行机制,谢谢分享。",
      "json_metadata": "{\"tags\":[\"cn\"],\"app\":\"steemit/0.1\"}",
      "parent_author": "tumutanzi",
      "parent_permlink": "re-justyy-re-tumutanzi-steemit-20170706t203552487z",
      "permlink": "re-tumutanzi-re-justyy-re-tumutanzi-steemit-20180118t155952628z",
      "title": ""
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-18T15:59:54",
  "trx_id": "a50941c361b7827fbe09618c1818b1b60d56f10d",
  "trx_in_block": 4,
  "virtual_op": 0
}
2018/01/18 15:40:48
idfollow
json["follow",{"follower":"semlinker","following":"abit","what":["blog"]}]
required auths[]
required posting auths["semlinker"]
Transaction InfoBlock #19089423/Trx 26105fc94f74dc57927727055851836f06f0048f
View Raw JSON Data
{
  "block": 19089423,
  "op": [
    "custom_json",
    {
      "id": "follow",
      "json": "[\"follow\",{\"follower\":\"semlinker\",\"following\":\"abit\",\"what\":[\"blog\"]}]",
      "required_auths": [],
      "required_posting_auths": [
        "semlinker"
      ]
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-18T15:40:48",
  "trx_id": "26105fc94f74dc57927727055851836f06f0048f",
  "trx_in_block": 20,
  "virtual_op": 0
}
2018/01/18 15:37:21
idfollow
json["follow",{"follower":"semlinker","following":"tumutanzi","what":["blog"]}]
required auths[]
required posting auths["semlinker"]
Transaction InfoBlock #19089354/Trx 435c53b27aedea52ac626c26cdbf60ff7a37d22b
View Raw JSON Data
{
  "block": 19089354,
  "op": [
    "custom_json",
    {
      "id": "follow",
      "json": "[\"follow\",{\"follower\":\"semlinker\",\"following\":\"tumutanzi\",\"what\":[\"blog\"]}]",
      "required_auths": [],
      "required_posting_auths": [
        "semlinker"
      ]
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-18T15:37:21",
  "trx_id": "435c53b27aedea52ac626c26cdbf60ff7a37d22b",
  "trx_in_block": 83,
  "virtual_op": 0
}
2018/01/18 15:36:27
authorsemlinker
body“这些礼仪规则不只适应Steemit,也是我们每天现实生活和线上生活的礼仪原则。” —— 学习了,对新人来说很受用,谢谢!
json metadata{"tags":["cn"],"app":"steemit/0.1"}
parent authortumutanzi
parent permlink6gkhr-steemit
permlinkre-tumutanzi-6gkhr-steemit-20180118t153626345z
title
Transaction InfoBlock #19089336/Trx 77cea97fc9ea5cbbdc6989c8cf0cb6c1bad5eb38
View Raw JSON Data
{
  "block": 19089336,
  "op": [
    "comment",
    {
      "author": "semlinker",
      "body": "“这些礼仪规则不只适应Steemit,也是我们每天现实生活和线上生活的礼仪原则。” —— 学习了,对新人来说很受用,谢谢!",
      "json_metadata": "{\"tags\":[\"cn\"],\"app\":\"steemit/0.1\"}",
      "parent_author": "tumutanzi",
      "parent_permlink": "6gkhr-steemit",
      "permlink": "re-tumutanzi-6gkhr-steemit-20180118t153626345z",
      "title": ""
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-18T15:36:27",
  "trx_id": "77cea97fc9ea5cbbdc6989c8cf0cb6c1bad5eb38",
  "trx_in_block": 28,
  "virtual_op": 0
}
2018/01/18 15:29:00
authorlukestokes
permlinksteem-is-not-steemit-steem-is-more-valuable-than-steemit
votersemlinker
weight10000 (100.00%)
Transaction InfoBlock #19089187/Trx 7a32a208993113410a6d90941dd94d231324d54d
View Raw JSON Data
{
  "block": 19089187,
  "op": [
    "vote",
    {
      "author": "lukestokes",
      "permlink": "steem-is-not-steemit-steem-is-more-valuable-than-steemit",
      "voter": "semlinker",
      "weight": 10000
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-18T15:29:00",
  "trx_id": "7a32a208993113410a6d90941dd94d231324d54d",
  "trx_in_block": 9,
  "virtual_op": 0
}
semlinkerpublished a new post: pwa-service-workers
2018/01/18 13:37:27
authorsemlinker
body@@ -4177,52 +4177,52 @@ /DQm -dkesv6zGCkZ96zwXcJUZMFLz6TesPN1t1uFYw4r3ov1f +VvPkb6Dh6HypAEfcJY7m4daJLGqaFRvsb5SNMKBohocH /sw-
json metadata{"tags":["cn-programming","pwa","cn"],"image":["https://steemitimages.com/DQmRUzuKqD9yraRvRGWtePCcc4tvKssCVcxpLoxziPr4fsf/service-worker.png","https://steemitimages.com/DQmcR6xAHuAHyLKKceEzedXei8HvhwhFBvKPvTE4MWDVCiF/sw-registration.jpg","https://steemitimages.com/DQmX2Ko7BUQkmYvvBYdt36PKhfQYEZGFTNC6GCa41FCfHwb/dev-sw-tab.png","https://steemitimages.com/DQmVvPkb6Dh6HypAEfcJY7m4daJLGqaFRvsb5SNMKBohocH/sw-update.jpg","https://steemitimages.com/DQmdQ9QLBDozkVi6wiFeewfqxm6KJrrUNrZ7H3re2ba9dat/sw-lifecycle.png"],"links":["https://developers.google.com/web/progressive-web-apps/","https://support.mozilla.org/zh-CN/kb/%E9%9A%90%E7%A7%81%E6%B5%8F%E8%A7%88","https://developers.google.com/web/fundamentals/primers/service-workers/?hl=zh-cn#_2","https://caniuse.com/#search=service%20worker","https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb?hl=zh-cn","https://developers.google.com/web/ilt/pwa/introduction-to-progressive-web-app-architectures","https://developer.mozilla.org/zh-CN/docs/Web/API/Service_Worker_API","https://developers.google.com/web/fundamentals/codelabs/debugging-service-workers/?hl=zh-cn"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkcn-programming
permlinkpwa-service-workers
titlePWA 学习笔记之 Service Workers
Transaction InfoBlock #19086958/Trx 0ddac686375fa9fccc337305db001e849f6aa758
View Raw JSON Data
{
  "block": 19086958,
  "op": [
    "comment",
    {
      "author": "semlinker",
      "body": "@@ -4177,52 +4177,52 @@\n /DQm\n-dkesv6zGCkZ96zwXcJUZMFLz6TesPN1t1uFYw4r3ov1f\n+VvPkb6Dh6HypAEfcJY7m4daJLGqaFRvsb5SNMKBohocH\n /sw-\n",
      "json_metadata": "{\"tags\":[\"cn-programming\",\"pwa\",\"cn\"],\"image\":[\"https://steemitimages.com/DQmRUzuKqD9yraRvRGWtePCcc4tvKssCVcxpLoxziPr4fsf/service-worker.png\",\"https://steemitimages.com/DQmcR6xAHuAHyLKKceEzedXei8HvhwhFBvKPvTE4MWDVCiF/sw-registration.jpg\",\"https://steemitimages.com/DQmX2Ko7BUQkmYvvBYdt36PKhfQYEZGFTNC6GCa41FCfHwb/dev-sw-tab.png\",\"https://steemitimages.com/DQmVvPkb6Dh6HypAEfcJY7m4daJLGqaFRvsb5SNMKBohocH/sw-update.jpg\",\"https://steemitimages.com/DQmdQ9QLBDozkVi6wiFeewfqxm6KJrrUNrZ7H3re2ba9dat/sw-lifecycle.png\"],\"links\":[\"https://developers.google.com/web/progressive-web-apps/\",\"https://support.mozilla.org/zh-CN/kb/%E9%9A%90%E7%A7%81%E6%B5%8F%E8%A7%88\",\"https://developers.google.com/web/fundamentals/primers/service-workers/?hl=zh-cn#_2\",\"https://caniuse.com/#search=service%20worker\",\"https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb?hl=zh-cn\",\"https://developers.google.com/web/ilt/pwa/introduction-to-progressive-web-app-architectures\",\"https://developer.mozilla.org/zh-CN/docs/Web/API/Service_Worker_API\",\"https://developers.google.com/web/fundamentals/codelabs/debugging-service-workers/?hl=zh-cn\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "cn-programming",
      "permlink": "pwa-service-workers",
      "title": "PWA 学习笔记之 Service Workers"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-18T13:37:27",
  "trx_id": "0ddac686375fa9fccc337305db001e849f6aa758",
  "trx_in_block": 40,
  "virtual_op": 0
}
semlinkerpublished a new post: pwa-service-workers
2018/01/18 13:24:36
authorsemlinker
body@@ -194,16 +194,20 @@ e-worker +.png %5D(https: @@ -233,68 +233,79 @@ /DQm -Y9vvMsCo2y7S7mrvq8kJWRhFcgX8mnZF7JND1xQtQZqi/image +RUzuKqD9yraRvRGWtePCcc4tvKssCVcxpLoxziPr4fsf/service-worker .png)%0A%0A( -%E5%9B%BE%E7%89%87 +%E8%83%8C%E6%99%AF%E7%B4%A0%E6%9D%90 %E6%9D%A5%E6%BA%90%EF%BC%9A%5B
json metadata{"tags":["cn-programming","pwa","cn"],"image":["https://steemitimages.com/DQmRUzuKqD9yraRvRGWtePCcc4tvKssCVcxpLoxziPr4fsf/service-worker.png","https://steemitimages.com/DQmcR6xAHuAHyLKKceEzedXei8HvhwhFBvKPvTE4MWDVCiF/sw-registration.jpg","https://steemitimages.com/DQmX2Ko7BUQkmYvvBYdt36PKhfQYEZGFTNC6GCa41FCfHwb/dev-sw-tab.png","https://steemitimages.com/DQmdkesv6zGCkZ96zwXcJUZMFLz6TesPN1t1uFYw4r3ov1f/sw-update.jpg","https://steemitimages.com/DQmdQ9QLBDozkVi6wiFeewfqxm6KJrrUNrZ7H3re2ba9dat/sw-lifecycle.png"],"links":["https://developers.google.com/web/progressive-web-apps/","https://support.mozilla.org/zh-CN/kb/%E9%9A%90%E7%A7%81%E6%B5%8F%E8%A7%88","https://developers.google.com/web/fundamentals/primers/service-workers/?hl=zh-cn#_2","https://caniuse.com/#search=service%20worker","https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb?hl=zh-cn","https://developers.google.com/web/ilt/pwa/introduction-to-progressive-web-app-architectures","https://developer.mozilla.org/zh-CN/docs/Web/API/Service_Worker_API","https://developers.google.com/web/fundamentals/codelabs/debugging-service-workers/?hl=zh-cn"],"app":"steemit/0.1","format":"markdown"}
parent author
parent permlinkcn-programming
permlinkpwa-service-workers
titlePWA 学习笔记之 Service Workers
Transaction InfoBlock #19086701/Trx 1820f41893e49262fefeaf8aada575500c0a04c0
View Raw JSON Data
{
  "block": 19086701,
  "op": [
    "comment",
    {
      "author": "semlinker",
      "body": "@@ -194,16 +194,20 @@\n e-worker\n+.png\n %5D(https:\n@@ -233,68 +233,79 @@\n /DQm\n-Y9vvMsCo2y7S7mrvq8kJWRhFcgX8mnZF7JND1xQtQZqi/image\n+RUzuKqD9yraRvRGWtePCcc4tvKssCVcxpLoxziPr4fsf/service-worker\n .png)%0A%0A(\n-%E5%9B%BE%E7%89%87\n+%E8%83%8C%E6%99%AF%E7%B4%A0%E6%9D%90\n %E6%9D%A5%E6%BA%90%EF%BC%9A%5B\n",
      "json_metadata": "{\"tags\":[\"cn-programming\",\"pwa\",\"cn\"],\"image\":[\"https://steemitimages.com/DQmRUzuKqD9yraRvRGWtePCcc4tvKssCVcxpLoxziPr4fsf/service-worker.png\",\"https://steemitimages.com/DQmcR6xAHuAHyLKKceEzedXei8HvhwhFBvKPvTE4MWDVCiF/sw-registration.jpg\",\"https://steemitimages.com/DQmX2Ko7BUQkmYvvBYdt36PKhfQYEZGFTNC6GCa41FCfHwb/dev-sw-tab.png\",\"https://steemitimages.com/DQmdkesv6zGCkZ96zwXcJUZMFLz6TesPN1t1uFYw4r3ov1f/sw-update.jpg\",\"https://steemitimages.com/DQmdQ9QLBDozkVi6wiFeewfqxm6KJrrUNrZ7H3re2ba9dat/sw-lifecycle.png\"],\"links\":[\"https://developers.google.com/web/progressive-web-apps/\",\"https://support.mozilla.org/zh-CN/kb/%E9%9A%90%E7%A7%81%E6%B5%8F%E8%A7%88\",\"https://developers.google.com/web/fundamentals/primers/service-workers/?hl=zh-cn#_2\",\"https://caniuse.com/#search=service%20worker\",\"https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb?hl=zh-cn\",\"https://developers.google.com/web/ilt/pwa/introduction-to-progressive-web-app-architectures\",\"https://developer.mozilla.org/zh-CN/docs/Web/API/Service_Worker_API\",\"https://developers.google.com/web/fundamentals/codelabs/debugging-service-workers/?hl=zh-cn\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}",
      "parent_author": "",
      "parent_permlink": "cn-programming",
      "permlink": "pwa-service-workers",
      "title": "PWA 学习笔记之 Service Workers"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-18T13:24:36",
  "trx_id": "1820f41893e49262fefeaf8aada575500c0a04c0",
  "trx_in_block": 26,
  "virtual_op": 0
}
semlinkerpublished a new post: pwa-cachestorage-api
2018/01/18 13:21:45
authorsemlinker
body@@ -87,16 +87,238 @@ %E7%9A%84%E6%96%B9%E5%BC%8F%E5%8A%A0%E8%BD%BD%E3%80%82%0A%0A +!%5Bcache-storage-api.png%5D(https://steemitimages.com/DQmbvVXMTUosxY9Rr8y5bsWpTGdQxgC7FUZHx4JpY6QEmc6/cache-storage-api.png)%0A%0A(%E8%83%8C%E6%99%AF%E7%B4%A0%E6%9D%90%E6%9D%A5%E6%BA%90%EF%BC%9A%5BGoogle - progressive-web-apps%5D(https://developers.google.com/web/progressive-web-apps/))%0A%0A %E5%9C%A8 %5BPWA %E5%AD%A6
json metadata{"tags":["cn-programming","pwa","cn"],"links":["https://developers.google.com/web/progressive-web-apps/","https://steemit.com/cn-programming/@semlinker/pwa-fetch-api","https://developer.mozilla.org/zh-CN/docs/Web/API/CacheStorage"],"app":"steemit/0.1","format":"markdown","image":["https://steemitimages.com/DQmbvVXMTUosxY9Rr8y5bsWpTGdQxgC7FUZHx4JpY6QEmc6/cache-storage-api.png"]}
parent author
parent permlinkcn-programming
permlinkpwa-cachestorage-api
titlePWA 学习笔记之 CacheStorage API
Transaction InfoBlock #19086644/Trx 362bb362dedcd39e6d4a289f6c6e6ddb57b86e42
View Raw JSON Data
{
  "block": 19086644,
  "op": [
    "comment",
    {
      "author": "semlinker",
      "body": "@@ -87,16 +87,238 @@\n %E7%9A%84%E6%96%B9%E5%BC%8F%E5%8A%A0%E8%BD%BD%E3%80%82%0A%0A\n+!%5Bcache-storage-api.png%5D(https://steemitimages.com/DQmbvVXMTUosxY9Rr8y5bsWpTGdQxgC7FUZHx4JpY6QEmc6/cache-storage-api.png)%0A%0A(%E8%83%8C%E6%99%AF%E7%B4%A0%E6%9D%90%E6%9D%A5%E6%BA%90%EF%BC%9A%5BGoogle - progressive-web-apps%5D(https://developers.google.com/web/progressive-web-apps/))%0A%0A\n %E5%9C%A8 %5BPWA %E5%AD%A6\n",
      "json_metadata": "{\"tags\":[\"cn-programming\",\"pwa\",\"cn\"],\"links\":[\"https://developers.google.com/web/progressive-web-apps/\",\"https://steemit.com/cn-programming/@semlinker/pwa-fetch-api\",\"https://developer.mozilla.org/zh-CN/docs/Web/API/CacheStorage\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\",\"image\":[\"https://steemitimages.com/DQmbvVXMTUosxY9Rr8y5bsWpTGdQxgC7FUZHx4JpY6QEmc6/cache-storage-api.png\"]}",
      "parent_author": "",
      "parent_permlink": "cn-programming",
      "permlink": "pwa-cachestorage-api",
      "title": "PWA 学习笔记之 CacheStorage API"
    }
  ],
  "op_in_trx": 0,
  "timestamp": "2018-01-18T13:21:45",
  "trx_id": "362bb362dedcd39e6d4a289f6c6e6ddb57b86e42",
  "trx_in_block": 32,
  "virtual_op": 0
}

Account Metadata

POSTING JSON METADATA
profile{"profile_image":"https://sfault-avatar.b0.upaiyun.com/483/735/483735741-58c0cb69d67b6_big64"}
JSON METADATA
profile{"profile_image":"https://sfault-avatar.b0.upaiyun.com/483/735/483735741-58c0cb69d67b6_big64"}
{
  "posting_json_metadata": {
    "profile": {
      "profile_image": "https://sfault-avatar.b0.upaiyun.com/483/735/483735741-58c0cb69d67b6_big64"
    }
  },
  "json_metadata": {
    "profile": {
      "profile_image": "https://sfault-avatar.b0.upaiyun.com/483/735/483735741-58c0cb69d67b6_big64"
    }
  }
}

Auth Keys

Owner
Single Signature
Public Keys
STM7JVtz68DTc9viNTZcNgSJDrqKtFJH5TAicuLeWxFX6xQgdHN371/1
Active
Single Signature
Public Keys
STM8iBs6jPJ8nbkJSiykDpa8wB56Wdk7FJ2gwXbeNMsfYFCGkwNPx1/1
Posting
Single Signature
Public Keys
STM5sVLRTPTBYFGkt29kMDoqN6ay3QaV8W9pfRKvZkQih9Fp55FeF1/1
Memo
STM5AgN5T9XyVsrszQ9QWgzbVmwpBWimBGqMJwvYamaGMPhZokMRH
{
  "owner": {
    "account_auths": [],
    "key_auths": [
      [
        "STM7JVtz68DTc9viNTZcNgSJDrqKtFJH5TAicuLeWxFX6xQgdHN37",
        1
      ]
    ],
    "weight_threshold": 1
  },
  "active": {
    "account_auths": [],
    "key_auths": [
      [
        "STM8iBs6jPJ8nbkJSiykDpa8wB56Wdk7FJ2gwXbeNMsfYFCGkwNPx",
        1
      ]
    ],
    "weight_threshold": 1
  },
  "posting": {
    "account_auths": [],
    "key_auths": [
      [
        "STM5sVLRTPTBYFGkt29kMDoqN6ay3QaV8W9pfRKvZkQih9Fp55FeF",
        1
      ]
    ],
    "weight_threshold": 1
  },
  "memo": "STM5AgN5T9XyVsrszQ9QWgzbVmwpBWimBGqMJwvYamaGMPhZokMRH"
}

Witness Votes

0 / 30
No active witness votes.
[]