SQLの窓

2018年08月26日


ファイルを一つアップロード : FORM の target を IFRAME にして、PHP に JavaScript を書き出させて元のページにメッセージを表示させる

昨今、ファイルをアップロードするならば、JavsScript を駆使して UI を作成し、 $.ajax で送信したほうが簡潔になりますが、ベタな FORM の記述のみで送信してそれなりのレスポンスを得ようという処理です。

デモページ


画像をクリックするとデモページへ移動します

当然ですが、デモページで実際のアップロードはできません。しかし、結果を表示するにチェックを入れて送信すると、上の画像のように実際と同じ状態で情報をシミュレートします。

UI の構築を気楽に工夫できるように、twitter-bootstrap の 4.1.3 を組み込んでいます

IFRAME は本来非表示で、ここに JavaScript で右上のメッセージ(toastr.js)を表示するようにしていますが、デバッグ用としても使えるようにしており、その場合は PHP 側の $_FILES の中身が見れるようになっています。

type="file" の name 属性は target で固定して php 側で使用しています。
送信データの制限 データの制限はサーバに対する無意味なアクセスを遮断するアプローチと、アプリから見たデータの制限という二つのアプローチがあります。前者がもっとも重要で、それがなければ php.ini の upload_max_filesize 内であれば結果的にそのサイズまでは送信を許してしまいます。 ※ upload_max_filesize を超えると $_FILES そのものが空になるようです。 後者は、FORM 内の name="MAX_FILE_SIZE" の値で指定できますが、完全な対策ではありません。 そこで、対象ページのあるディレクトリの .htaccess 内に 『LimitRequestBody 102400』のように制限値を設定し、さらに『ErrorDocument 413』 を設定してそのページの中でエラー処理の対応をしています ▼ 413.html
<!DOCTYPE html>
<html lang="ja">
<meta charset="utf-8">
<style>
* {
	font-size: 32px;
}
</style>
<script>

	try {
		parent.$("iframe").show();
		parent.toastr.info( "ファイル のアップロードに失敗しました");
		parent.toastr.info( "エラー内容 : Request Entity Too Large" );
	}
	catch (e) {}

</script>
</head>
<body>

JavaScript の処理用に IFRAME を定義している場合で、
413 Request Entity Too Large が発生した場合にこのページが IFRAME 内に表示されます。

</body>
</html>


file_upload_html.php

$debug 変数で、実際のアップロードの可否を切り替えています。if ( !$_FILES ) { の部分は、upload_max_filesize を超えてしまった状態の対処ですが、ここでは LimitRequestBody 102400 を設定しているので発生する事はありません。
<?php
session_cache_limiter('nocache');
session_start();

header( "Content-Type: text/html; charset=utf-8" );

// *************************************
// 変数初期値
// *************************************
$debug = 0;
$upload_dir = "./upload";
if ( !$_FILES ) {
	// php.ini の upload_max_filesize を超えて、
	// Apache に制限が無いと $_FILE が空になる
	$_FILES['target']['error'] = 5;	// ユーザエラーメッセージ
}

// *************************************
// アップロード処理
// フィールド名 : target で固定
// *************************************
if ( $_SERVER['REQUEST_METHOD'] == "POST" ) {

	// 公開状態では実行しない
	if ( $debug == 1 ) {

		$upload = realpath ( $upload_dir );
		$upload .= ( DIRECTORY_SEPARATOR . $_FILES['target']['name'] );
		if ( move_uploaded_file(
			$_FILES['target']['tmp_name'], $upload ) ) {
			$_POST['result']  = "アップロードに成功しました";
		}
		else {
			if ( !$_FILES ) {
				$_FILES['target']['error'] = 5;	// ユーザエラーメッセージ
			}
			$_POST['result']  = "アップロードに失敗しました";
		}

	}
	else {
		if ( $_FILES['target']['error'] == 0 ) {
			$_POST['result']  = "アップロードに成功しました";
		}
		else {
			$_POST['result']  = "アップロードに失敗しました";
		}
	}

}
else {
	$_POST['result']  = "POST メソッドを使用して下さい";
}

$_POST['files'] = $_FILES;

// *************************************
// この JSON 文字列を HTML 内の json
// オブジェクト定義として埋め込みます
// *************************************
$json = json_encode($_POST, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE );


// *************************************
// 画面定義
// *************************************
?>
<!DOCTYPE html>
<html lang="ja">
<style>
/* calc 用 */
html,body {
	height: 100%;
}
body {
	margin: 0;
}

* {
	font-size: 16px;
	font-family: "ヒラギノ角ゴPro W6","Hiragino Kaku Gothic Pro W6","メイリオ",Meiryo,"MS Pゴシック",Verdana,Arial,Helvetica,sans-serif;
}
</style>
<script>
var message = <?php require("error.json.php") ?>
var json = <?= $json ?>;

if ( json.files.target.error == 0 ) {
	parent.toastr.info(json.files.target.name + " がアップロードされました");
	parent.toastr.info("ファイルサイズ : " + json.files.target.size);
}
else {
	parent.toastr.info(json.files.target.name + " のアップロードに失敗しました");
	parent.toastr.info("エラー内容 : " + message.error[json.files.target.error]);
}

<?php if( $_POST["disp_result"] == "1" ) { ?>

	parent.$("iframe[name='upload']")
		.css("border", "1px solid #c0c0c0")
		.show();

<?php } else { ?>

	parent.$("iframe[name='upload']").hide();

<?php } ?>

</script>
</head>
<body>
<?php if( $_POST["disp_result"] == "1" ) { ?>
<textarea style='width:calc(100% - 6px);height:calc(100% - 14px);'><?= $json ?></textarea>

<?php } ?>
</body>
</html>


error.json.php は、PHP のエラーメッセージです。ここでは部品として埋め込んでいますが、$.ajax バージョンでも使用(error.json.php?type=json)しています。

error.json.php
<?php
if ( $_GET["type"] == "json" ) {
	session_cache_limiter('nocache');
	session_start();
	header( "Content-Type: application/json; charset=utf-8" );
}

?>
{
	"error": [
		"0 - 正常終了",
		"1 - アップロードされたファイルは、php.ini の upload_max_filesize ディレクティブの値を超えています",
		"2 - アップロードされたファイルは、HTML フォームで指定された MAX_FILE_SIZE を超えています",
		"3 - アップロードされたファイルは一部のみしかアップロードされていません",
		"4 - ファイルはアップロードされませんでした",
		"5 - 『アップロードに失敗しました』",
		"6 - テンポラリフォルダがありません。PHP 5.0.3 で導入されました",
		"7 - ディスクへの書き込みに失敗しました。PHP 5.1.0 で導入されました",
		"8 - PHP の拡張モジュールがファイルのアップロードを中止しました"
	]
}


upload.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta content="width=device-width initial-scale=1.0 minimum-scale=1.0 maximum-scale=1.0 user-scalable=no" name="viewport">
<title>HTML の FORM のみでファイルを一つアップロードする</title>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link id="link" rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/base/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/2.1.4/toastr.min.css">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/2.1.4/toastr.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.qrcode/1.0/jquery.qrcode.min.js"></script>

<!-- 共通の表示 -->
<link rel="stylesheet" href="common.css">

<!-- CSS の指定 -->
<style>
#top {
	height: 420px;
}
iframe {
	display: block;
	margin-left: auto;
	margin-right: auto;
	width: calc( 100% - 3px );
	height: calc( 100% - 420px - 2px );
}

/* PC 用の表示 */
@media screen and ( min-width:480px ) {
	#content {
		margin: 16px;
	}
}
/* スマホ用の表示 */
@media screen and ( max-width:479px ) {
	#content {
		margin: 0px;
	}
	body {
		width: 100%!important;
		margin: 0px;
	}
	.unit {
		width: 100%;
	}
	.btn {
		margin-top: 7px;
	}
}
</style>
<script>
// 簡易的なスマホチェックを jQuery のプロパティとして登録
jQuery.isMobile = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase()));
if ( $.isMobile ) {
	// スマホの場合は表示画面下の中央
	toastr.options.positionClass = "toast-bottom-center";
}

$(function(){

	// このページ自身の QRコードの表示
	$('#qrcode')
		.css({ "margin" : "2px" })
		.qrcode({width: 160,height: 160,text: location.href });
		

});
</script>
</head>
<body>
<div id="top">
	<div id="head">
		<div id="title">
			<a href="./">One File アップロード</a>
		</div>
	</div>

	<div id="content">
		<form target="upload" enctype="multipart/form-data" action="../../php_upload/file_upload_html.php" method="POST">
			<input type="hidden" name="MAX_FILE_SIZE" value="40000">
			<input name="target" type="file" class="btn btn-info">
			<input type="submit" value="ファイルを送信" class="btn btn-success ml-2">

			<p>
				<label for="disp_result">結果を表示する</label>
				<input id="disp_result" type="checkbox" name="disp_result" value="1" class="mt-5" checked>
			</p>
		</form>

		<div id="qrcode"></div>

	</div>

</div>


<iframe src="about:blank" name="upload" style="display:none;border:0px solid #c0c0c0;width:100%;"></iframe>



</body>
</html>


common.css
@charset "UTF-8";

/* calc 用 */
html,body {
	height: 100%;
}
body {
	margin: 0;
}

/* 共通の表示 */
* {
	font-size: 16px;
	font-family: "ヒラギノ角ゴPro W6","Hiragino Kaku Gothic Pro W6","メイリオ",Meiryo,"MS Pゴシック",Verdana,Arial,Helvetica,sans-serif;
}
#head {
	background-color: #404040;
	padding: 10px 0 10px 25px;
}
#head * {
	color: #ffffff;
}



HTML 側のダウンロード



PHP 側のダウンロード





【PHP + 通信の最新記事】
posted by lightbox at 2018-08-26 21:35 | PHP + 通信 | このブログの読者になる | 更新情報をチェックする

2018年08月25日


Oracle : ユーザ(スキーマ)の作成

他のデータベースと違って、Oracle ではユーザを作成する事は、create database と同じ意味になりますが、ユーザだけ作成しても権限が全く無く、利用可能にするには権限を持つユーザが、権限を与える必要があります。

開発環境が一つの Oracle の場合はやみくもに以下の処理を行う事はできませんが、PC 内に自由に使える Oracle をインストールした場合は以下の手順でユーザを作成するといいと思います。

1) 作成するユーザ専用のテーブルスペース作成
 ( テーブルスペースは共有できますが、開発管理上別々のほうが良い )
2) ユーザ作成
3) 権限を与える

※ 一連の作業は SYSTEM ユーザで行って下さい。

create tablespace LIGHTBOX_SPACE
	datafile 'C:\ORACLEXE\ORADATA\XE\LIGHTBOX.DBF'
	size 5M
	autoextend on
	next 1M
	maxsize unlimited
	segment space management AUTO;

create user LIGHTBOX
	identified by LIGHTBOX
	default tablespace LIGHTBOX_SPACE
	temporary tablespace TEMP
	quota unlimited on LIGHTBOX_SPACE
	account UNLOCK;

grant 
	 ALTER PROFILE
	,ALTER SESSION
	,ALTER SYSTEM
	,ALTER TABLESPACE
	,ALTER USER
	,CREATE ANY DIRECTORY
	,CREATE PROCEDURE
	,CREATE PROFILE
	,CREATE PUBLIC SYNONYM
	,CREATE ROLE
	,CREATE ROLLBACK SEGMENT
	,CREATE SEQUENCE
	,CREATE SESSION
	,CREATE SYNONYM
	,CREATE TABLE
	,CREATE TABLESPACE
	,CREATE TRIGGER
	,CREATE VIEW
	,DROP ANY DIRECTORY
	,EXECUTE ANY PROCEDURE
	,SELECT ANY DICTIONARY
	,SELECT ANY SEQUENCE
	,SELECT ANY TABLE
to LIGHTBOX;

TEMP は、Oracle をインストールした時に作成される一般的な一時用表領域です。一つの PC で開発環境を作るのであれば TEMP を使うといいと思います。

datafile の場所は、ハードディスクであればどこでもいいですが、開発管理上、既にインストールされている場所が良いと思います。拡張子は .dbf である必要はありません。ユーザが作成した表領域である事を明示する為に、.ORA のように変更してもかまいません。


関連する記事

Oracle 10g Express Edition のインストール
サービス開始 : Oracle 10g Express
Oracle インストール後の初期設定

Oracle11g + Windows : PC名を変更してしまった場合の対処方法



posted by lightbox at 2018-08-25 23:26 | Oracle : 環境 | このブログの読者になる | 更新情報をチェックする

2018年08月10日


IE11 で『安全だとマークされていないActiveX』を使用可能にして実行可能な Windows 処理のサンプル

HTA(HTMLアプリケーション) のコードを html として IE11 でデバッグする方法 を行って、localhost や イントラネットのサーバを信頼するサイトに登録すると使えます。

実行は JavaScript で簡単な関数を用意して実行します。
ごみ箱 explorer.exe /n,::{645FF040-5081-101B-9F08-00AA002F954E}
ファイル名を指定して実行 rundll32.exe shell32.dll,#61
インイストールされたソフトウェア(プログラムと機能) rundll32.exe shell32.dll,Control_RunDLL appwiz.cpl
ネットワーク接続 rundll32.exe shell32.dll,Control_RunDLL ncpa.cpl
環境変数ダイアログ rundll32.exe sysdm.cpl,EditEnvironmentVariables
Windows Update control.exe /name Microsoft.WindowsUpdate
デバイスマネージャ control.exe /name Microsoft.DeviceManager
フォルダオプション rundll32.exe shell32.dll,Options_RunDLL 7
ネットワークドライブの割り当てダイアログ rundll32.exe shell32.dll,SHHelpShortcuts_RunDLL Connect
デスクトップアイコンの設定 control.exe desk.cpl,,0
メモ帳 notepad.exe
ペイント mspaint.exe
電卓 calc.exe
プリンタ一覧 control.exe /name Microsoft.DevicesAndPrinters
Microsoft Excel excel.exe
Microsoft Word winword.exe
マイドキュメント explorer C:\Users\%USERNAME%\Documents
リソープリンタ 管理ページ rundll32.exe url.dll,FileProtocolHandler http://192.168.10.37/
デスクトップの アプリケーション.mde C:\Users\%USERNAME%\Desktop\アプリケーション.mde
デスクトップの Book1.xlsx C:\Users\%USERNAME%\Desktop\Book1.xlsx
\\コンピューター名\共有 \\pc01\mydata\2018

用意する JavaScript の処理
<script>
function newObject( className ) {

	var obj;

	try {
		obj = new ActiveXObject( className );
	}
	catch (e) {
		obj = null;
	}

	return obj;

}

var wsh = newObject("WScript.Shell");

function wshRun( strPath ) {

	wsh.Run( "RunDLL32.EXE url.dll,FileProtocolHandler " + "\"" + strPath + "\"" )

}

function wshRunExe( strPath ) {

	wsh.Run( strPath )

}

</script>

Windows の一般アプリケーション(.exe) は、wshRunExe を使用します。拡張子による実行には、ファイルのパスを渡して wshRun を使用します。( strPath に渡すパス内の文字列は HTML 上に文字列として置く場合、 \ が \\ となるようにします )

\\コンピューター名\共有 のネットワーク参照は、A 要素で href に指定してエクスプローラで開く事ができます。




posted by lightbox at 2018-08-10 16:38 | IE | このブログの読者になる | 更新情報をチェックする

2018年07月31日


HTA (または IE11) で フォルダ選択ダイアログからフォルダとファイルの一覧


IE11 での実行には設定が必要です => HTA(HTMLアプリケーション) のコードを html として IE11 でデバッグする方法
※ newObject 関数は、hta.js で定義しています。 ▼ BrowseForFolder メソッド
var objFolder = objShell.BrowseForFolder( 0, "フォルダ選択", 1, 0 );
フォルダ参照 第1引数は、本来はウインドウハンドルを渡すものですが、こでは 0 を設定します。 第2引数は、タイトルの下に表示される文字列です。 第3引数は、BROWSEINFO structure の ulFlags の内容ですが実際はここに書いてある通りになはならないので試してみる他ありません。ここでは、1 を渡しており、意味は( Only return file system directories. If the user selects folders that are not part of the file system, the OK button is grayed ) です。=> ファイルシステム以外だと OK ボタンが 灰色になって使用できません 第4引数は、ShellSpecialFolderConstants のフォルダを渡して、そのフォルダを一番上のフォルダにします。=> ここでは、0 なのでデスクトップです。 一覧作成 フォルダオブジェクトを取得して、Items メソッドで下位のファイルとフォルダのコレクション( FolderItems オブジェクト )を取得します。 さらに、FolderItems オブジェクト の Item メソッドFolderItem オブジェクトを取得します。 IsFolder プロパティName プロパティを使用して一覧を作成します Name プロパティは、配列にセットして sort メソッドでソートしてから、区切りとルートフォルダのパスをセットしてテーブル要素に表示します Self プロパティは 仕様上は Folder2 オブジェクトとなります ▼ HTA(HTML アプリケーション) : pcname-from-stdout.hta ▼ IE11 : pcname-from-stdout.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="x-ua-compatible" content="ie=edge" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.1/css/bootstrap.css" />
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>

<script src="https://winofsql.jp/hta.js"></script>

<script>

	// ウインドウの位置とサイズ
	centerWindow( 1100, 600 );

	// Windows Shaell
	var objShell = newObject("Shell.Application");

	$(function(){
	
		// ***************************
		// ボタン表示位置微調整
		// ***************************
		$( ".btn" ).css({
			"margin-top": "-4px"
		});
	
		// ***************************
		// フォルダの選択後
		// フォルダ内の一覧
		// ***************************
		$("#act1").on("click", function(){

			// 1:0固定, 2:タイトル, 3:ファイルシステムのみ, 4:ルートがデスクトップ
			var objFolder = objShell.BrowseForFolder( 0, "フォルダ選択", 1, 0 );
			if ( objFolder == null ) {
				alert("フォルダの選択がキャンセルされました");
				return;
			}
			if ( !objFolder.Self.IsFileSystem ) {
				alert("ファイルシステムではありません");
				return;
			}
			
			var objFolderItems = objFolder.Items();
			
			var arrData = [];

			var nFiles = objFolderItems.Count;
			for( i = 0; i < nFiles; i++ ) {
				var objItem = objFolderItems.Item(i)
				if ( objItem.isFolder ) {
					arrData.push( " [" + objItem.Name +"]" );
				}
				else {
					arrData.push( objItem.Name );
				}
			}

			arrData.sort();
			arrData.unshift("-------------------------------------------------------------");
			arrData.unshift(objFolder.Self.Path);
			
			loadTable( arrData );

		});

	});

</script>

<style>
html,body {
	height: 100%;
}

body {
	margin: 0;
}

/* ブロックを左右に表示  */
.ttl {
	display: inline-block;
	width: 120px;
	vertical-align: top;
}
.entry {
	display: inline-block;
}
.line {
	margin-bottom: 0;
}

#head {
	padding: 16px;
}

/* IFRAMEコントロール用  */
#head {
	padding: 16px;
	width: 100%;
	height: 120px;
	background-color: #e0e0e0;
}
#extend {
	padding: 4px 16px;
	display: block;
	margin-left: auto;
	margin-right: auto;
	width: calc( 100% - 3px );
	height: calc( 100% - 120px - 2px );
	border: solid 2px #c0c0c0;
	overflow: scroll;
}
.row_data td {
	cursor: default!important;
}

</style>

</head>
<body>
<div id="head">

	<p class="ttl">
		処理
	</p>
	<p class="entry">

		<input
			id="act1"
			class="ml-4 btn btn-outline-primary"
			type="button"
			value="フォルダ選択(Shell.Application)">

	</p>
	<p class="line"></p>

	<h4 class="text-danger"></h4>

</div>
<div id="extend">
	<table class="table table-hover">
		<tbody id="tbl">
		</tbody>
	</table>
<br>
</div>

</body>
</html>


hta.js




posted by lightbox at 2018-07-31 20:03 | HTA ( HTMLアプリケーション ) | このブログの読者になる | 更新情報をチェックする

2018年07月28日


HTA (または IE11) で hostname を実行して標準出力からPC名の取得


IE11 での実行には設定が必要です => HTA(HTMLアプリケーション) のコードを html として IE11 でデバッグする方法
コマンドプロンプトベースのアプリケーションを実行するので、一瞬コマンドプロンプトが現れます。その後、コマンドプロンプトに表示された内容を取得する方法です。 ※ StdOut は、TextStream オブジェクトのメソッドで処理に該当するものが使えます。 ※ WshScriptExec オブジェクト ▼ HTA(HTML アプリケーション) : pcname-from-stdout.hta ▼ IE11 : pcname-from-stdout.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="x-ua-compatible" content="ie=edge" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.1/css/bootstrap.css" />
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>

<script src="hta.js"></script>

<script>

	// ウインドウの位置とサイズ
	centerWindow( 1100, 600 );

	// WSH 標準
	var WshShell = newObject("WScript.Shell");

	$(function(){
	
		// ***************************
		// ボタン表示位置微調整
		// ***************************
		$( ".btn" ).css({
			"margin-top": "-4px"
		});
	
		// ***************************
		// hostname を実行して
		// 結果を取得する
		// ***************************
		$("#act1").on("click", function(){

			var oExec = WshShell.Exec("hostname");
			var str = "";
			str += oExec.StdOut.ReadAll();

			var arrData = [ str ];
			loadTable( arrData );

		});


	});

</script>

<style>
html,body {
	height: 100%;
}

body {
	margin: 0;
}

/* ブロックを左右に表示  */
.ttl {
	display: inline-block;
	width: 120px;
	vertical-align: top;
}
.entry {
	display: inline-block;
}
.line {
	margin-bottom: 0;
}

#head {
	padding: 16px;
}

/* IFRAMEコントロール用  */
#head {
	padding: 16px;
	width: 100%;
	height: 120px;
	background-color: #e0e0e0;
}
#extend {
	padding: 4px 16px;
	display: block;
	margin-left: auto;
	margin-right: auto;
	width: calc( 100% - 3px );
	height: calc( 100% - 120px - 2px );
	border: solid 2px #c0c0c0;
	overflow: scroll;
}
.row_data td {
	cursor: default!important;
}

</style>

</head>
<body>
<div id="head">

	<p class="ttl">
		処理
	</p>
	<p class="entry">

		<input
			id="act1"
			class="ml-4 btn btn-outline-primary"
			type="button"
			value="hostname を実行して標準出力からPC名の取得">

	</p>
	<p class="line"></p>

	<h4 class="text-danger"></h4>

</div>
<div id="extend">
	<table class="table table-hover">
		<tbody id="tbl">
		</tbody>
	</table>
<br>
</div>

</body>
</html>


hta.js
// *************************************
// ウインドウの位置とサイズ
// *************************************
function baseWindow( x, y, w, h ) {

	top.moveTo( x, y );
	top.resizeTo( w, h );

}

// *************************************
// デスクトップ中央
// *************************************
function centerWindow( w, h ) {

	// ウインドウの位置とサイズ
	top.resizeTo( w, h );
	top.moveTo((screen.width-w)/2, (screen.height-h)/2 )

}

// *************************************
// CreateObject
// *************************************
function newObject( className ) {

	var obj;

	try {
		obj = new ActiveXObject( className );
	}
	catch (e) {
		obj = null;
	}

	return obj;

}

// *************************************
// テーブル作成
// *************************************
function loadTable( arrayData ) {

	var row_data = "";

	// テーブル表示リセット
	$("#tbl .row_data").remove();
	
	var len = arrayData.length;
	for( i = 0; i < len; i++ ) {
		row_data = $("<tr></tr>")
			.addClass("row_data")
			.appendTo( "#tbl" );

		$("<td></td>")
			.text(arrayData[i])
			.appendTo( row_data );
	
	}

}





posted by lightbox at 2018-07-28 22:28 | HTA ( HTMLアプリケーション ) | このブログの読者になる | 更新情報をチェックする

2018年07月24日


HTA : 『x-frame-options: SAMEORIGIN』の設定されていないページの情報を IFRAME 内に表示して jQuery で取り出す / iframe内 参照と .clone() と .end()

レスポンスヘッダーに x-frame-options: SAMEORIGIN が設定されているとそのページは同一ドメインでないと IFRAME に読み込んで表示する事ができません。

さらに、x-frame-options: SAMEORIGIN が設定されていなくても、通常のブラウザであれば表示する事はできても、JavaScript でアクセスする事ができません。

IFRAME 内に x-frame-options: SAMEORIGIN の設定されていない WEB ページを表示してかつ、JavaScript で値を取り出せるのは HTA だけです。





<html>
<head>
<meta http-equiv="x-ua-compatible" content="ie=edge" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.1/css/bootstrap.css" />
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>

<script>
// *************************************
// デスクトップ中央
// *************************************
function centerWindow( w, h ) {

	// ウインドウの位置とサイズ
	top.resizeTo( w, h );
	top.moveTo((screen.width-w)/2, (screen.height-h)/2 )

}
</script>

<script>

	// ウインドウの位置とサイズ
	centerWindow( 860, 600 );

	// テーブルの行作成用
	var row_data = "";

	$(function(){

		// レジストリキーの値一覧
		$("#act").on("click", function(){
		
			var domdoc = $("iframe[name='extend']").get(0).contentWindow.document;

			$(domdoc).find("#datalist p").each( function(idx){
			
				row_data = $("<tr></tr>")
					.addClass("row_data")
					.appendTo( "#tbl" );

				// 複製を取得して複製内の span を削除して
				// .end() で参照を p_clone に戻す
				var p_clone = $(this).clone().find("span").remove().end();
				// 複製内の span を削除 
				
				// p 内にある span のテキスト
				$("<td></td>")
					.text($(this).find("span").text())
					.appendTo( row_data );

				// span が削除された p 内のテキスト
				$("<td></td>")
					.text(p_clone.text())
					.appendTo( row_data );

			});

		});

		// 再表示
		$("#view").on("click", function(){
			location.reload(true);
		});

		// IE のドキュメントモードを表示
		$("<div></div>")
			.text( document.documentMode )
			.css( { "float" : "right", "color": "#808080", "font-size": "8px" } )
			.insertBefore( $("p").eq(0) );
			

		// ボタン表示位置微調整
		$( ".btn" ).css({
			"margin-top": "-4px"
		});
			
		
	});

</script>

<style>
/* ブロックを左右に表示  */
.ttl {
	display: inline-block;
	width: 230px;
	vertical-align: top;
}
.entry {
	display: inline-block;
}
.line {
	margin-bottom: 0;
}

#head {
	padding: 16px;
}

/* DIV を Window 下部にフィット  */
html,body {
	height: 100%;
}

body {
	margin: 0;
}
#head {
	padding: 16px;
	width: 100%;
	height: 120px;
	background-color: #e0e0e0;
}
.extend {
	padding: 4px 16px;
	display: block;
	margin-left: auto;
	margin-right: auto;
	width: calc( 100% - 3px );
	height: calc( 100% - 120px - 2px );
	border: solid 2px #c0c0c0;
	overflow: scroll;
}

/* テーブルのカーソル用  */
.row_data td, .row_data th {
	cursor: default!important;
	white-space: pre;
}

</style>
</head>
<body>
<div id="head">

	<p class="ttl">
		外部IFRAMEの内容を取り出す
	</p>

	<p class="entry">
		<input
			id="act"
			class="ml-4 btn btn-outline-primary"
			type="button"
			value="一覧表示">

		<input
			class="ml-4 btn btn-info btn-sm"
			id="view"
			type="button"
			value="再表示">
	</p>
	<p class="line"></p>

	<h4 class="text-danger"></h4>

</div>
<div class="extend">
	<table class="table table-hover">
		<tbody id="tbl">
		</tbody>
	</table>
<br>
</div>

<iframe class="extend" name="extend" APPLICATION="yes" src="https://lightbox.sakura.ne.jp/demo/iframe_target.html"></iframe>

</body>
</html>


jQuery でテキストノードの文字列を取り出す

以下のような HTML では、テキスト がテキストノードにあたります。テキスト2 はテキストノードでは無いので、a に対するセレクタで取得できますが、テキストと同様の方法で取り出します。

参考 : [Javascript] jQueryでテキストノードを選択するにはどうすればよいですか?
<div id="datalist">
	<p><span>18/07/23</span>テキスト</p>
	<p><span>18/07/22</span>テキスト</p>
	<p><span>18/07/18</span>テキスト</p>
	<p><span>18/07/16</span><a href="URL">テキスト2</a></p>
	<p><span>18/07/15</span><a href="URL">テキスト2</a></p>
	<p><span>18/07/15</span><a href="URL">テキスト2</a></p>
</div></body>


IFRAME 内のドキュメント参照と .clone() と .end()

1) var domdoc = $("iframe[name='extend']").get(0).contentWindow.document で、DOM として IFRAME 内の document を取得します

2) テキストノードを取得する為に span を削除する必要があるので、clone() で同じものを作成してその中から span を削除します

3) 削除した段階で、参照が span に移行しているので、end() で一つ前に戻って、そこから text() でデータを取得します
var domdoc = $("iframe[name='extend']").get(0).contentWindow.document;

$(domdoc).find("#datalist p").each( function(idx){

	row_data = $("<tr></tr>")
		.addClass("row_data")
		.appendTo( "#tbl" );

	// 複製を取得して複製内の span を削除して
	// .end() で参照を p_clone に戻す
	var p_clone = $(this).clone().find("span").remove().end();
	// 複製内の span を削除 
	
	// p 内にある span のテキスト
	$("<td></td>")
		.text($(this).find("span").text())
		.appendTo( row_data );

	// span が削除された p 内のテキスト
	$("<td></td>")
		.text(p_clone.text())
		.appendTo( row_data );

});


WEB ページのデータを HTA で自動的に取得したい場合、x-frame-options: SAMEORIGIN がなければそのまま使えます。しかし、一般的には欲しいページをダウンロードしてローカルに置いて読み込めば全てのページのデータをある程度自動取得できます。




posted by lightbox at 2018-07-24 23:57 | HTA ( HTMLアプリケーション ) | このブログの読者になる | 更新情報をチェックする
container 終わり

フリーフォントで簡単ロゴ作成
フリーフォントでボタン素材作成
フリーフォントで吹き出し画像作成
フリーフォントではんこ画像作成
ほぼ自由に利用できるフリーフォント
フリーフォントの書体見本とサンプル
画像を大きく見る為のウインドウを開くボタンの作成

CSS ドロップシャドウの参考デモ
BUTTONS (CSS でボタン)
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり