ajaxでブラウザからアクセス不可にするにはこうすればいいのか

ajaxjQueryをサクッと使用

  • 受け取る側
<?php
try {
    if (($_SERVER['HTTP_X_REQUESTED_WITH'] ?? '') !== 'XMLHttpRequest') {
        throw new Exception("ブラウザからアクセスきんし\n");
    }

    switch ($_GET['id']) {
        case 1:
            echo "田中";
            break;
        default:
            echo "なし";
            break;
    }
    
}catch(Exception $e){
    exit($e->getMessage());
}
  • 送る側
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    
<label>ID:<input type="number" name="name" value=""></label>
<input type="button" value="送信">
<p>名前:<span></span></p>

<script src="//code.jquery.com/jquery-3.1.1.min.js"></script>
<script>
$(function() {
    $("[type=button]").on("click", function() {

        $.get("sample.php", {
            id : $("[type=number]").val()
        }, function(data) {
            $("span").text(data);
        });

    });
});
</script>
</body>
</html>

f:id:okumuraa1:20180219210704g:plain


でもcurl使えばアクセスできてしまうという

f:id:okumuraa1:20180219211827p:plain

reactjs.orgをただ読んでいくだけ その1

reactjs.org とりあえず、トップページを読みます。

f:id:okumuraa1:20180218152856p:plain


reactを使うメリットはこんな感じらしい

f:id:okumuraa1:20180218201840p:plain


JSXはやっぱりいいなあ

f:id:okumuraa1:20180218195957g:plain


一回勉強したことあるから、タイマーの原理くらいはわかる!

f:id:okumuraa1:20180218200322p:plain


最後のマークダウンのやつだけ、コピペしただけだと動かないのか、

f:id:okumuraa1:20180218201139p:plain

$ npm install remarkable --save
import React from 'react';
import ReactDOM,{ render } from 'react-dom';
import Remarkable from 'remarkable';

class MarkdownEditor extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.state = { value: 'Type some *markdown* here!' };
  }

  handleChange(e) {
    this.setState({ value: e.target.value });
  }

  getRawMarkup() {
    const md = new Remarkable();
    return { __html: md.render(this.state.value) };
  }

  render() {
    return (
      <div className="MarkdownEditor">
        <h3>Input</h3>
        <textarea
          onChange={this.handleChange}
          defaultValue={this.state.value}
        />
        <h3>Output</h3>
        <div
          className="content"
          dangerouslySetInnerHTML={this.getRawMarkup()}
        />
      </div>
    );
  }
}

ReactDOM.render(
  <MarkdownEditor />,
  document.getElementById('app')
);

f:id:okumuraa1:20180218201658g:plain

動いた!

socket.ioのドキュメントのGet startedを読めばリアルタイム双方向通信チャットが簡単に作れるので実際に動かして見た

socket.ioを勉強したいなと思っていましたので、とりあえず、公式ドキュメントのGet startedを読んで実際に動かして見ました

Socket.IO — Chat


f:id:okumuraa1:20180205232920p:plain


以下、ソースコードコピペです。

package.json

{
  "name": "socket-chat-example",
  "version": "0.0.1",
  "description": "my first socket.io app",
  "dependencies": {
    "express": "^4.15.2",
    "socket.io": "^1.7.3"
  },
  "scripts": {
    "start": "node index.js"
  }
}
$ npm i --save

index.js

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var port = process.env.PORT || 3000;

app.get('/', function(req, res){
  res.sendFile(__dirname + '/index.html');
});

io.on('connection', function(socket){
  socket.on('chat message', function(msg){
    io.emit('chat message', msg);
  });
});

http.listen(port, function(){
  console.log('listening on *:' + port);
});

index.html

<!doctype html>
<html>
  <head>
    <title>Socket.IO chat</title>
    <style>
      * { margin: 0; padding: 0; box-sizing: border-box; }
      body { font: 13px Helvetica, Arial; }
      form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
      form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
      form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
      #messages { list-style-type: none; margin: 0; padding: 0; }
      #messages li { padding: 5px 10px; }
      #messages li:nth-child(odd) { background: #eee; }
      #messages { margin-bottom: 40px }
    </style>
  </head>
  <body>
    <ul id="messages"></ul>
    <form action="">
      <input id="m" autocomplete="off" /><button>Send</button>
    </form>
    <script src="https://cdn.socket.io/socket.io-1.2.0.js"></script>
    <script src="https://code.jquery.com/jquery-1.11.1.js"></script>
    <script>
      $(function () {
        var socket = io();
        $('form').submit(function(){
          socket.emit('chat message', $('#m').val());
          $('#m').val('');
          return false;
        });
        socket.on('chat message', function(msg){
          $('#messages').append($('<li>').text(msg));
          window.scrollTo(0, document.body.scrollHeight);
        });
      });
    </script>
  </body>
</html>
$ npm run start

f:id:okumuraa1:20180205230639g:plain

WebSocketの基本を知りたかったので自分なりに検索して見た

とりあえず読んでみたページを貼っていくだけです。


Wikipedia

WebSocket - Wikipedia

チャットシステムとか作るのに向いているというは、こういうことなのか。

f:id:okumuraa1:20180204144537p:plain

f:id:okumuraa1:20180204145301p:plain


RFC 6455

自分はRFC読んでもわからない単語が多いのですが、それでも読んで見ます。

RFC 6455 - The WebSocket Protocol

f:id:okumuraa1:20180204150812p:plain
通信についてもっと勉強しないとな

f:id:okumuraa1:20180204151342p:plain
やっぱりこういうドキュメントは書き方が難しいですね

WebSocket protocol alterations

Wikipediaからのリンクを読んで見た

https://fetch.spec.whatwg.org/#websocket-protocol

f:id:okumuraa1:20180204162156p:plain
とりあえずgoogle翻訳して読むだけ読んでみる

Qiita

読んで見ました。


qiita.com

WebSocket 事始め by Node.js + Socket.IO - Qiita

websocket-railsで簡単なPush通知を実装する - Qiita

qiita.com

qiita.com


今度Node.jsでプログラム組むぞ!

javascriptで音楽再生

javascriptでどんなことができるかぐらい知っておきたいので、音楽再生をちょっと試してみました。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <h1>audio</h1>
<script>
const audio = new Audio("./sample.mp3");
audio.play();
</script>
</body>
</html>

f:id:okumuraa1:20180129211639g:plain

気象庁の気象データ(最低気温)をMySQLに保存する

以下のページから気象庁のデータをcsv形式で取得できるため、 それをMySQLに保存するプログラムをphpでざっくり書いてみました。 www.data.jma.go.jp


index.php

<?php
try{
    $pdo = new PDO(
        "mysql:dbname=test;host=127.0.0.1;charset=utf8mb4;",
        'root',
        '',
        [
            PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE=>PDO::FETCH_NUM,
        ]
    );

    $pdo->exec(
        "CREATE TABLE IF NOT EXISTS lowest(
            `観測所番号` INT(11) NOT NULL PRIMARY KEY
           ,`都道府県` VARCHAR(50)
           ,`地点` VARCHAR(50)
           ,`国際地点番号` INT(11)
           ,`現在時刻(年)` INT(11)
           ,`現在時刻(月)` INT(2) ZEROFILL
           ,`現在時刻(日)` INT(2) ZEROFILL
           ,`現在時刻(時)` INT(2) ZEROFILL
           ,`現在時刻(分)` INT(2) ZEROFILL
           ,`今日の最低気温(℃)` FLOAT
           ,`今日の最低気温の品質情報` INT(2)
           ,`今日の最低気温起時(時)` INT(2) ZEROFILL
           ,`今日の最低気温起時(分)` INT(2) ZEROFILL
           ,`今日の最低気温起時の品質情報` INT(2)
           ,`平年差(℃)` FLOAT
           ,`前日差(℃)` FLOAT
           ,`該当旬(月)` INT(2)
           ,`該当旬(旬)`     INT(2)
           ,`極値更新` INT(2)
           ,`10年未満での極値更新` INT(2)
           ,`今季最低` INT(2)
           ,`今年の最低気温(℃)(昨日まで)` FLOAT
           ,`今年の最低気温(昨日まで)の品質情報` INT(2)
           ,`今年の最低気温(昨日まで)を観測した起日(年)` INT(11)
           ,`今年の最低気温(昨日まで)を観測した起日(月)` INT(2) ZEROFILL
           ,`今年の最低気温(昨日まで)を観測した起日(日)` INT(2) ZEROFILL
           ,`昨日までの観測史上1位の値(℃)` FLOAT
           ,`昨日までの観測史上1位の値の品質情報` INT(2)
           ,`昨日までの観測史上1位の値を観測した起日(年)` INT(2)
           ,`昨日までの観測史上1位の値を観測した起日(月)` INT(2) ZEROFILL
           ,`昨日までの観測史上1位の値を観測した起日(日)` INT(2) ZEROFILL
           ,`昨日までの1月の1位の値` FLOAT
           ,`昨日までの1月の1位の値の品質情報` INT(2)
           ,`昨日までの1月の1位の値の起日(年)` INT(2)
           ,`昨日までの1月の1位の値の起日(月)` INT(2) ZEROFILL
           ,`昨日までの1月の1位の値の起日(日)` INT(2) ZEROFILL
           ,`統計開始年` INT(11)
       ) DEFAULT CHARSET=utf8;"
    );

    $pdo->exec(
        "TRUNCATE TABLE lowest;
         LOAD DATA INFILE '".str_replace('\\','/',__DIR__)."/lowest.csv'
         INTO TABLE lowest
         FIELDS TERMINATED BY ','
         IGNORE 1 LINES
         (
             @field1
            ,@field2
            ,@field3
            ,@field4
            ,@field5
            ,@field6
            ,@field7
            ,@field8
            ,@field9
            ,@field10
            ,@field11
            ,@field12
            ,@field13
            ,@field14
            ,@field15
            ,@field16
            ,@field17
            ,@field18
            ,@field19
            ,@field20
            ,@field21
            ,@field22
            ,@field23
            ,@field24
            ,@field25
            ,@field26
            ,@field27
            ,@field28
            ,@field29
            ,@field30
            ,@field31
            ,@field32
            ,@field33
            ,@field34
            ,@field35
            ,@field36
            ,@field37
        )
        SET 
             `観測所番号` = nullif(@field1,'')
            ,`都道府県` = nullif(@field2,'')
            ,`地点` = nullif(@field3,'')
            ,`国際地点番号` = nullif(@field4,'')
            ,`現在時刻(年)` = nullif(@field5,'')
            ,`現在時刻(月)` = nullif(@field6,'')
            ,`現在時刻(日)` = nullif(@field7,'')
            ,`現在時刻(時)` = nullif(@field8,'')
            ,`現在時刻(分)` = nullif(@field9,'')
            ,`今日の最低気温(℃)` = nullif(@field10,'')
            ,`今日の最低気温の品質情報` = nullif(@field11,'')
            ,`今日の最低気温起時(時)` = nullif(@field12,'')
            ,`今日の最低気温起時(分)` = nullif(@field13,'')
            ,`今日の最低気温起時の品質情報` = nullif(@field14,'')
            ,`平年差(℃)` = nullif(@field15,'')
            ,`前日差(℃)` = nullif(@field16,'')
            ,`該当旬(月)` = nullif(@field17,'')
            ,`該当旬(旬)` = nullif(@field18,'')
            ,`極値更新` = nullif(@field19,'')
            ,`10年未満での極値更新` = nullif(@field20,'')
            ,`今季最低` = nullif(@field21,'')
            ,`今年の最低気温(℃)(昨日まで)` = nullif(@field22,'')
            ,`今年の最低気温(昨日まで)の品質情報` = nullif(@field23,'')
            ,`今年の最低気温(昨日まで)を観測した起日(年)` = nullif(@field24,'')
            ,`今年の最低気温(昨日まで)を観測した起日(月)` = nullif(@field25,'')
            ,`今年の最低気温(昨日まで)を観測した起日(日)` = nullif(@field26,'')
            ,`昨日までの観測史上1位の値(℃)` = nullif(@field27,'')
            ,`昨日までの観測史上1位の値の品質情報` = nullif(@field28,'')
            ,`昨日までの観測史上1位の値を観測した起日(年)` = nullif(@field29,'')
            ,`昨日までの観測史上1位の値を観測した起日(月)` = nullif(@field30,'')
            ,`昨日までの観測史上1位の値を観測した起日(日)` = nullif(@field31,'')
            ,`昨日までの1月の1位の値` = nullif(@field32,'')
            ,`昨日までの1月の1位の値の品質情報` = nullif(@field33,'')
            ,`昨日までの1月の1位の値の起日(年)` = nullif(@field34,'')
            ,`昨日までの1月の1位の値の起日(月)` = nullif(@field35,'')
            ,`昨日までの1月の1位の値の起日(日)` = nullif(@field36,'')
            ,`統計開始年` = nullif(@field37,'');"
        );

        // 都道府県ごとの最低気温を出力する
        $query=$pdo->query(
            "SELECT CONCAT(
                      STR_TO_DATE(CONCAT(`現在時刻(年)`,`現在時刻(月)`,`現在時刻(日)`,`現在時刻(時)`,`現在時刻(分)`),'%Y%m%d%H%i')
                     ,'\t',`今日の最低気温(℃)`
                     ,'\t',`都道府県`
                     ,'\n'
                    )
             FROM lowest
             WHERE `観測所番号` IN (
                SELECT MAX(`観測所番号`)
                FROM lowest
                WHERE ((`都道府県`,`今日の最低気温(℃)`)IN(
                    SELECT `都道府県`,MIN(`今日の最低気温(℃)`)
                    FROM lowest
                    GROUP BY `都道府県`
                ))
                GROUP BY `都道府県`
             )"
        );

        header('Content-Type:text/plain;charset=UTF-8');
        foreach($query->fetchAll() as $key => $r){
            echo $r[0];
        }

}catch(PDOException $e){
    exit($e->getMessage());
}

以下のページのcsvデータをlowest.csvとして、phpと同じ場所に保存 http://www.data.jma.go.jp/obd/stats/data/mdrr/tem_rct/alltable/mntemsadext00_rct.csv


php実行

f:id:okumuraa1:20180127181550p:plain

北海道寒い!

Parcelを触って見ました。

Everything You Need To Know About Parcel: The Blazing Fast Web App Bundler 🚀

上のページをもとにparcelの基本を勉強して見ました。


parcelインストール

$ npm init -y
$ npm install parcel-bundler --save-dev

index.html、index.js、package.jsonを書いてる通りに作成し、$ yarn start

f:id:okumuraa1:20171229110454g:plain

無事parcelが動きました!


ビルド時間早い!

f:id:okumuraa1:20171229110619p:plain


勝手にlocalhost:1234で動いてくれる!

f:id:okumuraa1:20171229110712g:plain


SCSS

f:id:okumuraa1:20171229111323g:plain

scssも普通にコンパイルしてくれた、設定ファイル書かなくていいのが、parcelのいいところなんだな


react.js

f:id:okumuraa1:20171229111524g:plain

.babelrcとかは必要


vue.js

f:id:okumuraa1:20171229111652g:plain

vueとreact併用できるんだな


typescrpt

f:id:okumuraa1:20171229111841g:plain

最後はtypescritp


感想

ローカルでさくっとフレームワークやライブラリを試すときに便利そう!