2018年02月19日


MSXML2.XMLHTTPでファイルをPOSTする

MSXML2.XMLHTTPでファイルをアップロードする と対になる処理です。受けるほうは通常と同じで簡単ですが、送るほうは注意すべき点がいくつかあります

まず、送るほうでは日本語を URL エンコードする必要があるので、JavaScript を呼び出して encodeURIComponent を使用しています。( その為、PHP ではデコードされると UTF-8 になるので注意 )

後、http で POST する際の仕様として、http ヘッダに Content-Type として application/x-www-form-urlencoded をセットしています( データサイズは実際ブラウザが行っているのでセットしています。)

VBSCript 側
<JOB>
<SCRIPT language="JScript">
function js(str) {

	return encodeURIComponent( str );

}
</SCRIPT>

<SCRIPT language="VBScript">

' XMLHTTP を作成
Set objHTTP = Wscript.CreateObject("Msxml2.ServerXMLHTTP")
lResolve = 60 * 1000
lConnect = 60 * 1000
lSend = 60 * 1000
lReceive = 60 * 1000

Call objHTTP.Open("POST","https://yourdomain/test/post.php",False)
Call objHTTP.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
strData = "data=" & js("日本語をURLエンコードする")
Call objHTTP.SetRequestHeader("Content-Length",Len(strData))
Call objHTTP.setTimeouts(lResolve, lConnect, lSend, lReceive)
Call objHTTP.Send(strData)
Wscript.Echo objHTTP.responseText

</SCRIPT>

</JOB>


PHP 側
<?php
header( "Content-Type: text/html; charset=utf-8" );
header( "Expires: Thu, 19 Nov 1981 08:52:00 GMT" );
header( "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0" );
header( "Pragma: no-cache" );

mb_language( "ja" );
mb_internal_encoding("utf-8");

foreach( $_POST as $key => $value ) {
	// $_GET の中には変換前が残る
	$_GET[$key] = $value;
	// $_POST を HTML 埋め込み用変数として使用する
	$_POST[$key] = htmlentities( $value );
}

if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {

	// ファイルへ入力されたデータを書き込み
	file_put_contents( "text.dat", mb_convert_encoding( $_GET['data'], "shift_jis", "utf-8" ) );

	print "POST処理を受付けました";

}

?>
<form method="post">
<input type="text" name="data" value="<?= $_POST["data"] ?>">
<input type="submit" name="send" value="送信">
</form>





posted by at 2018-02-19 17:57 | クライアント/サーバー | このブログの読者になる | 更新情報をチェックする

2018年02月18日


MSXML2.(Server)XMLHTTPでファイルをアップロードする

呼び出し側は WSH としての VBScript です。バイナリとしてアップロードするので、CRLF は CRLF のままなので、LF へ変換が必要なファイルやシステムでは、サーバー側で変換する必要があります

PHP ならそのままで問題無いので、わざわざ 通常の POST 仕様にあわせる必要も無いと思います。

VBScript 側のサンプルは Microsoft の サポートオンラインにあるので、IIS ではうまくいくのかとは思うのですが、試してはいません。いずれにしても、IIS に対して行う場合はテストが必要です

テストはさくらインターネットの環境で行っています。PHP は、5.6.32 でした。

いったん PNG 画像をアップロードして、FileZilla でダウンロードして fc /b で比較しましたが問題無く同じものでした。テキストファイルも同じ結果で CRLF のままで返って来ています。ただ、rb wb を rt wt にしてもアップロードされたものは同じでした。ドキュメント通り、Windows の PHP 環境のみで効果があるのかもしれませんが、テストはできていません。

最初記事を書いたころは、MSXML2.XMLHTTP というクライアント用のオブジェクトを使用していましたが、Microsoft 側の変遷で現在は MSXML2.ServerXMLHTTP のほうが信頼性が高いと判断して使用しています。
upload.vbs
' *************************************
' サーバーオブジェクトを使用しています
' *************************************
Set objHTTP = Wscript.CreateObject("Msxml2.ServerXMLHTTP")
lResolve = 60 * 1000
lConnect = 60 * 1000
lSend = 60 * 1000
lReceive = 60 * 1000

' Stream オブジェクト の作成
Set Stream = CreateObject("ADODB.Stream")
' Stream のオープン
Stream.Open
' Stream タイプの指定
Stream.Type = 1		' StreamTypeEnum の adTypeBinary
' 既存ファイルの内容を Stream に読み込む
Stream.LoadFromFile "target.png"

' ▼ ご自分の環境に書き換えてください。
Call objHTTP.Open("POST","https://yourdomain/test/put.php",False)

nLen = Stream.Size
data = Stream.Read(nLen)

Call objHTTP.SetRequestHeader("Content-Length",nLen)
Call objHTTP.setTimeouts(lResolve, lConnect, lSend, lReceive)
Call objHTTP.Send(data)

Wscript.Echo objHTTP.responseText
 
' Stream を閉じる
Stream.Close


put.php
<?PHP
header( "Content-Type: text/html; charset=utf-8" );

$id = uniqid();

$fp = fopen( "php://input", "rb" );
$wfp = fopen( "data/{$id}_upload.dat", "wb" );

while( $ret = fread( $fp, 4096 ) ) {

	fwrite( $wfp, $ret );

}

fclose($wfp);
fclose($fp);


?>
データが保存されました


PHP は utf-8 で書いています。それ以外のキャラクタセットの場合は、http ヘッダに同じように設定しておかないと、XMLHTTP が日本語の変換をできないので注意して下さい。通常通り、使用しているキャラクタセットと http ヘッダを一致させればどのキャラクタセットでも問題ありません。

※ HTML 等の静的ページでは、サーバ側でキャラクタセツトの設定ができない場合は、UTF-8 扱いになってしまいます


 関連する記事

PHP + VBS 分割ダウンロード
バッチ処理的ファイルのコピー
MSXML2.XMLHTTPでファイルをPOSTする
prototype.js の Ajax.Request を使い、FORM を使わずにデータをPOSTする



posted by at 2018-02-18 16:12 | クライアント/サーバー | このブログの読者になる | 更新情報をチェックする

2014年11月27日


Seesaa が『この広告は1年以上更新がないブログに表示されております。』という広告を表示しています。

新規投稿でないと対象にならないようです。info.seesaa.net をドメイン内検索をしても、該当するものは無いので突然の仕様変更かもしれません。

ブックマークレット : Googleのドメイン内検索を任意のページで実行




ソースを表示して、一番下までスクロールすると、以下のような記述があります。
<p style="margin:0;padding:0;font-size:10px;color:#DDD;">この広告は1年以上更新がないブログに表示されております。</p>
</div>
<script type="text/javascript">
//<![CDATA[
document.getElementById('seesaa-bnr-close').addEventListener('click', function(){ document.getElementById('seesaa-bnr').style.display = 'none'; });
//]]>
</script>
<script type="text/javascript">
var url = document.URL;
document.write("<img src='http://d3mgo879eugsjh.cloudfront.net/t.gif?url=" + encodeURIComponent(url) + "' />");
</script>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
<script type="text/javascript">
var nend_params = {"media":3,"site":3,"spot":57750,"type":2,"oriented":1,"sp":0};
</script>
<script type="text/javascript" src="http://js1.nend.net/js/nendAdLoader.js"></script>
<script type="text/javascript" src="http://t.seesaa.net/analytics-seesaa-net.js?v=20141014&tid=UA-53911882-1"></script>



posted by at 2014-11-27 23:16 | クライアント/サーバー | このブログの読者になる | 更新情報をチェックする

2010年12月01日


Google MAP API 経由で Panoramio を表示する場合、Google Chrome のみ 常に手前に出てしまうので、wmode を 後から transparent に変更

http://lightbox.on.coocan.jp/pano_mio_view2.html?1788181&400&266

上は単純に参照に使っているだけですが、panoramio の表示そのものをサムネイルにする為
に透過画像を重ねると、Google Chrome だけが手前になってしまいます。そこで、完全では
ありませんが、0.5 秒後に param を全て書き換えています。

ですから、重ねる処理が必要無い場合は、wmode の書き換え処理は必要ありません
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html
	xmlns="http://www.w3.org/1999/xhtml"
	xmlns:v="urn:schemas-microsoft-com:vml"
>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title></title>

<script
	src="http://maps.google.com/maps?file=api&amp;v=2.17&amp;sensor=false&amp;key=ABQIAAAADuryzsZi1CenwhafsPEvzBRS10rmJJPhM3vlpPkrWCHuNTDImRTYfD_FN1NxrjVEOgXa8q0JiFN0CQ"
	type="text/javascript"
></script>

<script type="text/javascript">
var params = (location.search + "&&&&&&&&&").replace("?","");
var param = params.split("&");
if ( param[1] == '' ) {
	param[1] = "800px";
}
else {
	param[1] += "px";
}
if ( param[2] == '' ) {
	param[2] = "600px";
}
else {
	param[2] += "px";
}

var myPano;
function initialize() {

	var panoOpts = { 
		features: { streetView: false, userPhotos: true },
		userPhotoOptions: { photoRepositories: [ 'panoramio'] } 
	}; 

	myPano = new GStreetviewPanorama(document.getElementById("pano"), panoOpts);
	var fenway = { repository: "panoramio", id: param[0] }; 
	GEvent.addListener(myPano, "error", handleNoFlash);

	// 表示
	myPano.setUserPhoto(fenway);
}

function handleNoFlash(errorCode) {

	if (errorCode == 603) {
		alert("Error: Flash doesn't appear to be supported by your browser");
		return;
	}
}
function changeFlash() {

	var target = document.getElementById("pano");
	var obj = target.getElementsByTagName("OBJECT")[0];
	var param = obj.innerHTML;

	var re;
	re = /<param\s+?name\s*=\s*([\"'])?wmode([\"'])?[^>]*>/;
	param = param.replace(re, "<param name=\"wmode\" value=\"transparent\">");
	obj.innerHTML = param;

}

function addEvent( obj, evt, callback_func ) {
	if ( obj.attachEvent ) {
		obj.attachEvent( "on" + evt , callback_func );
	}
	else {
		obj.addEventListener( evt , callback_func , false );
	}
}
// Google Chrome の場合 flash の wmode を transparent に変更
var userAgent = window.navigator.userAgent.toLowerCase();
if (userAgent.indexOf("chrome") > -1) {
	addEvent(window, 'load', function(){ setTimeout( "changeFlash()", 500 );});
}
</script>
</head>
<body onload="initialize()" onunload="GUnload()">
<div name="pano" id="pano"></div>
<script type="text/javascript">
document.getElementById("pano").style.width = param[1];
document.getElementById("pano").style.height = param[2];
</script>
</body>
</html>



posted by at 2010-12-01 14:40 | クライアント/サーバー | このブログの読者になる | 更新情報をチェックする

2009年07月03日


prototype.js の Ajax.Request を使い、FORM を使わずにデータをPOSTする

MSXML2.XMLHTTPでファイルをPOSTする と同系列で、IE で実行する場合、結局prototype.js内では
MSXML2.XMLHTTPを使っています。VBScriptで通常のアプリケーションとして実行する
場合と違って、同一ドメイン内でのみ実行可能です。
<?
header( "Content-Type: text/html; Charset=shift_jis" );
header( "pragma: no-cache" );
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "Cache-control: no-cache" );

foreach( $_GET as $Key => $Value ) {
	$_POST[$Key] = $_GET[$Key];
}
foreach( $_POST as $Key => $Value ) {
	$_POST[$Key] = str_replace("\\\\", "\\", $Value );
	$_POST[$Key] = str_replace("\\'", "'", $_POST[$Key] );
	$_POST[$Key] = str_replace("\\\"", "\"", $_POST[$Key] );
}

if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {

	// ファイルへ入力されたデータを書き込み
	file_put_contents( "text.dat", $_POST['text'] );
	print "データはUTF-8で受信しています";
	exit();

}

?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=shift_jis" />

<script
	src="http://www.google.com/jsapi"
	type="text/javascript"
	charset="utf-8"
></script>
<script type="text/javascript">

// Google で HOSTINGされているライブラリを使う
google.load("prototype", "1.6");

// *********************************************************
// HTTP 通信
// *********************************************************
function postText(text) {

	// ■ サーバー側コードは 自分自身
	// ■ GET
	// ■ 同期処理
	// ■ target=filename
	// オブジェクト作成 = イベント作成です
	new Ajax.Request("<?= $_SERVER['PHP_SELF'] ?>",
	{
		method: "post",
		asynchronous: false,
		parameters: { "text" : text },

		onSuccess: function(request) {
			// 成功した事が保証される
		},
		onComplete: function(request) {
			$("text").value = request.responseText;
		},
		onFailure: function(request) {
			alert('読み込みに失敗しました   ');
		}
	}
	);
}

</script>

</head>
<body>

<input type=button value="初期画面" onClick='location.href="<?= $_SERVER['PHP_SELF'] ?>"'>
&nbsp;
<input type=button value="HTTP通信" onClick='postText($("text").value);'>
<br>
<textarea id=text name=text cols=80 rows=15></textarea>


</body>
</html>

■ 関連する記事
prototype.js の Ajax.Request の encoding パラメータ


posted by at 2009-07-03 15:31 | クライアント/サーバー | このブログの読者になる | 更新情報をチェックする
Seesaa の各ページの表示について
Seesaa の 記事がたまに全く表示されない場合があります。その場合は、設定> 詳細設定> ブログ設定 で 最新の情報に更新の『実行ボタン』で記事やアーカイブが最新にビルドされます。

Seesaa のページで、アーカイブとタグページは要注意です。タグページはコンテンツが全く無い状態になりますし、アーカイブページも歯抜けページはコンテンツが存在しないのにページが表示されてしまいます。

また、カテゴリページもそういう意味では完全ではありません。『カテゴリID-番号』というフォーマットで表示されるページですが、実際存在するより大きな番号でも表示されてしまいます。

※ インデックスページのみ、実際の記事数を超えたページを指定しても最後のページが表示されるようです

対処としては、このようなヘルプ的な情報を固定でページの最後に表示するようにするといいでしょう。具体的には、メインの記事コンテンツの下に『自由形式』を追加し、アーカイブとカテゴリページでのみ表示するように設定し、コンテンツを用意するといいと思います。


※ エキスパートモードで表示しています

アーカイブとカテゴリページはこのように簡単に設定できますが、タグページは HTML 設定を直接変更して、以下の『タグページでのみ表示される内容』の記述方法で設定する必要があります

<% if:page_name eq 'archive' -%>
アーカイブページでのみ表示される内容
<% /if %>

<% if:page_name eq 'category' -%>
カテゴリページでのみ表示される内容
<% /if %>

<% if:page_name eq 'tag' -%>
タグページでのみ表示される内容
<% /if %>
この記述は、以下の場所で使用します