任何人都可以帮我保存画布图像到SQL? database = registration ... table:users .... column:username,image [longblob]

时间:2017-06-22 11:13:19

标签: javascript mysql

直接说我不清楚JS(所以我不明白在sql中存储图像的任何逻辑)...我只是一个学习者[一年级的CE学生] ...虽然我学会了后端( sql,php)我必须提交这个项目,但我是股票....我完全不知道将图像直接存储到sql,因为我点击“继续”按钮....所有的朋友都是新手,我不喜欢没有足够的时间学习JS ......有许多解决方案可用,但我不理解其中任何一个......请帮助我维护我的代码....谢谢

<?php include('server.php'); ?>
<!DOCTYPE html>
<html>
<head>
  <title>HIMALAYA COLLEGE EXIBITION</title>
	<link rel="stylesheet" type="text/css" href="style.css">
  	<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Tangerine">
 </head>
 <body>
 <br>
 <br>
 <br>
 <div class="capture">
	<video id="video" width="400" height="300" title="capture your photo" autoplay></video>
	<button id="snap" name="snap">Snap Photo</button>
	<br>
	<canvas id="canvas" width="400" height="300"></canvas>
	<br><br>
	<a href="#" id="afterimage">Continue</a>
	
</div>
<script>
// Grab elements, create settings, etc.
var video = document.getElementById('video');

// Get access to the camera!
if(navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
    // Not adding `{ audio: true }` since we only want video now
    navigator.mediaDevices.getUserMedia({ video: true }).then(function(stream) {
        video.src = window.URL.createObjectURL(stream);
        video.play();
    });
}
//setup
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var video = document.getElementById('video');

// Trigger photo take
document.getElementById("snap").addEventListener("click", function() {
	context.drawImage(video, 0, 0, 400, 300);

});
</script>

<br>
</body>
</html>

2 个答案:

答案 0 :(得分:1)

因此,您的脚本已经能够从视频中拍摄快照。现在,您必须将画布数据转换为blob并通过ajax将其发送到服务器。现代浏览器并不是特别困难。

document.getElementById('snap').addEventListener('click', function() {
  context.drawImage(video, 0, 0, 400, 300);
  canvas.toBlob(function (blob) {
    var req = new XMLHttpRequest();
    req.open('POST', 'uploadimage.php');

    req.onload = function () {
      console.log('upload complete, server response:', req.response);
    };

    console.log('uploading snapshot...');
    req.send(blob);
  });
});

打开控制台(F12)以查看日志消息。在制作中,您必须为用户生成HTML反馈。

服务器部分有点复杂。首先,创建一个名为uploadimage.php的PHP脚本。此脚本将使用php://input流检索上传的文件。

与处理用户提交的数据一样,您需要执行一些安全检查。您想验证上传的文件是图像类型(请参阅mime_content_type)。

您还需要对用户进行身份验证,以便不允许每个人(或任何机器人)将内容上传到您的服务器。我不会告诉你如何做到这一点,这超出了本主题的范围。

最后,我们需要选择一个不会与现有文件名冲突的文件名。一个好的候选者是基于当前时间的字符串(参见microtime)。您可能还想添加与经过身份验证的用户相关的前缀。

编辑:好吧,对不起,我忘了你想把它存储在数据库中。告诉我你是否设法调整这个脚本。如果没有,我会写一个更合适的回复。)

<?php
header('Content-Type: text/plain; charset=utf-8');

define('PREFIX', 'banana-');

$fd = fopen('php://input', 'rb');
$mimeType = mime_content_type($fd);
fclose($fd);
$matchResult = preg_match('#^image/(\w+)#', $mimeType, $matches);

if ($matchResult === false) {
    header('HTTP/1.0 500 Internal Server Error');
    echo "Couldn't parse MIME type";
}
else if ($matchResult === 0) {
    header('HTTP/1.0 400 Bad Request');
    echo "Wrong MIME type";
}
else {
    $fileExt = $matches[1];
    $fileName = PREFIX . number_format(microtime(true), 6, '-', '') . '.' . $fileExt;

    $putResult = file_put_contents($fileName, file_get_contents('php://input'));
    if ($putResult === false) {
        header('HTTP/1.0 500 Internal Server Error');
        echo "Couldn't write file";
    }
    else {
        echo 'Ok';
    }
}

编辑2:随着我的进步而更新。这个问题比我想象的要复杂得多。当我们想要将blob与其他POST数据混合时,我们似乎无法使用php://input - 这些将是身份验证所必需的。

现在我有一个功能性的后端脚本来接收和存储图像,但没有身份验证。

<?php
header('Content-Type: text/plain; charset=utf-8');
ini_set('html_errors', '0');

function sendError($message, $code = 500) {
    header("HTTP/1.0 $code");
    die($message);
}

$fd = fopen('php://input', 'rb');
$mimeType = mime_content_type($fd);
fclose($fd);

$matchResult = preg_match('#^image/#', $mimeType);

if ($matchResult === false) {
    sendError("Couldn't parse MIME type");
}
if ($matchResult === 0) {
    sendError('Wrong MIME type', 400);
}

$mysqli = new mysqli('localhost:3306', 'root', '', 'registration');
if ($mysqli->connect_error) {
    sendError($mysqli->connect_error);
}
$mysqli->set_charset('utf8mb4') or sendError($mysqli->error);

$username = 'Homer';
$contents = file_get_contents('php://input');

$query = 'INSERT INTO uploads (username, file) VALUES (?, ?)';
$stmt = $mysqli->prepare($query)              or sendError($mysqli->error);
$stmt->bind_param('ss', $username, $contents) or sendError($stmt->error);
$stmt->execute()                              or sendError($stmt->error);

echo 'Ok';

编辑3:我们在这里。要通过ajax上传混合内容,FormData会有更大的帮助。要在服务器端接收它,请使用$_FILES的经典方式。

我最终发现,为了验证用户,最好的方法是使用会话。事实上,您甚至不需要额外的请求参数,但让我们坚持使用FormData解决方案,因为您可能希望发送元数据和一些安全措施,例如:一个CSRF token

这是更新的客户端脚本:

document.getElementById('snap').addEventListener('click', function() {
  context.drawImage(video, 0, 0, 400, 300);
  canvas.toBlob(function (blob) {
    var formData = new FormData();
    formData.append('snapshot', blob);
    formData.append('image-description', 'MFW Im writing an answer on SO');

    var req = new XMLHttpRequest();
    req.open('POST', 'uploadimage.php');

    req.onload = function () {
      console.log('upload complete, server response:', req.response);
    };

    console.log('uploading snapshot...');
    req.send(formData);
  });
});

更新的服务器脚本:

<?php
header('Content-Type: text/plain; charset=utf-8');
ini_set('html_errors', '0');

function sendError($message, $code = 500) {
    header("HTTP/1.0 $code");
    die($message);
}

session_start();
if (!isset($_SESSION['username'])) sendError('Please log in', 401);

if (!isset($_FILES['snapshot'])) sendError('Missing file', 400);

$fd = fopen($_FILES['snapshot']['tmp_name'], 'rb');
$mimeType = mime_content_type($fd);
fclose($fd);

$matchResult = preg_match('#^image/#', $mimeType);

if ($matchResult === false) {
    sendError("Couldn't parse MIME type");
}
if ($matchResult === 0) {
    sendError('Wrong MIME type', 400);
}

$mysqli = new mysqli('localhost:3306', 'root', '', 'registration');
if ($mysqli->connect_error) {
    sendError($mysqli->connect_error);
}
$mysqli->set_charset('utf8mb4') or sendError($mysqli->error);

$username = $_SESSION['username'];
$contents = file_get_contents($_FILES['snapshot']['tmp_name']);

$query = 'INSERT INTO uploads (username, file) VALUES (?, ?)';
$stmt = $mysqli->prepare($query)              or sendError($mysqli->error);
$stmt->bind_param('ss', $username, $contents) or sendError($stmt->error);
$stmt->execute()                              or sendError($stmt->error);

echo 'Ok';

关于HTTP代码的说明:我尝试用某种有意义的代码响应,例如REST API端点。但我认为HTTP代码是个人意见的问题,我并不认为我选择了更合适的代码。随意更改它们,或者根本不使用它们。

答案 1 :(得分:0)

https://stackoverflow.com/users/2221034/watilin 在mysql ......数据库名称 - 注册..... table-name:users .... column:username,batch,password_1,password_2,image(blob).... 我使用apache作为服务器(XAMPP)并且所有页面(registration.php,login.php)都连接到下面显示的server.php

&#13;
&#13;
<?php
	session_start();

	$username = "";
	$errors = array();
	/*if( ! empty( $_POST )) {
		print_r($_POST);}*/
	//connect to the database
	$db = mysqli_connect('localhost:3306', 'root', '', 'registration');
	/*if($db->connect_error){
		echo'sorry';
	}*/
	//if register button is clicked
	//link with the register
	if(isset($_POST['register'])){
			$username = $_POST['username'];
			$batch = $_POST['batch'];
			$password_1 = $_POST['password_1'];
			$password_2 = $_POST['password_2'];
			//ensure that the form are filled properly
			if(empty($username)){
				array_push($errors,"Username is required!!!");
			}
			if(empty($batch)){
				array_push($errors,"Batch is required!!!");
			}
			if(empty($password_1)){
				array_push($errors,"Password is required!!!");
			}
			if($password_1 != $password_2)
			{
				array_push($errors,"password do not match!!!");
			}
			//if no error save user to database
			if (count($errors)==0)
			{
				$password = md5($password_1);//encrypt password before storing in database(security)
				//$sql = "INSERT INTO users (username,batch,password) VALUES ('$username', '$batch', '$password')";
				mysqli_query($db,"INSERT INTO users (username, batch, password_1, password_2) VALUES ('$username', '$batch', '$password','$password')");
				$_SESSION['username'] = $username;
				$_SESSION['success'] = "you are now registered ^_^";
				header('location: index.php'); //redirect to home page

			}
	}
	//log user in from login page
	if (isset($_POST['login'])) {
		$username = $_POST['username'];
		$password = $_POST['password_1'];

		//ensure that the forms are filled properly
		if(empty($username)) {
			array_push($errors, "Username is required");
		}
		if(empty($password))
		{
			array_push($errors, "Password is required");
		}
		if(count($errors) == 0) {
	 		$password = md5($password);//encrypting password
	 		$query = "SELECT * FROM users WHERE username='$username' AND password_1='$password'";
	 		$result = mysqli_query($db, $query);
	 	if(mysqli_num_rows($result) == 1) {
	 		//log user in
	 			$_SESSION['username'] = $username;
				$_SESSION['success'] = "you are now logged in ^_^";
				header('location: index2.php');//redirecting to home page
 
		 }
		 else{
		 		array_push($errors,"wrong username or password");
		 }
		}
	}




?>
&#13;
&#13;
&#13;