如何在 AngularJS 中使用 VisualCaptcha 并在 RESTful 中使用 slimPHP
How to use VisualCaptcha with AngularJS and slimPHP in RESTful
所以我在前端使用 AngularJS
,在后端使用 SlimPHP
和 REST url。我正在尝试使用 VisualCaptch 并且我按照 PHP 方面的说明进行操作并且它似乎在后端工作,我做了一个简单的 Angular 数据服务调用 url 和在控制台上显示它,但我根本不明白如何将它与 Angular 连接,我也下载了那部分,但是当我创建 HTML
并在 <div>
。好吧,实际上让我解释一下问题 1,Angular 试图 运行 的 url 是不正确的,但我只是不知道如何配置它,有没有选项?所以让我展示一下我到目前为止的代码...顺便说一下,我使用 Controller as vm
语法,所以你不会在我的代码中找到 $scope
。
HTML:
<div captcha options="vm.captchaOptions"></div>
AngularJS 控制器代码:
// this work as a dataService call to SlimPHP
dataService.getCaptchaHowMany().then(function(data) {
console.debug(data);
});
// where does my dataService call goes in here???
vm.captchaOptions = {
imgPath: 'vendors/visual-captcha/img/',
captcha: { numberOfImages: 5 },
init: function ( captcha ) {
vm.captcha = captcha;
}
};
SlimPHP 路线,我知道它们有效
# Captcha Routes
$app->get('/captcha/start/:howMany', function($howMany) use ($app) { CaptchaController::getCaptchaHowMany($app, $howMany); });
$app->get('/captcha/audio(/:type)', function($type = 'mp3') use ($app) { CaptchaController::getCatpchaDiskAudioStreaming($app, $type); });
$app->get('/captcha/image/:index', function($index) use ($app) { CaptchaController::getCatpchaDiskImageStreaming($app, $index); });
$app->post('/captcha/try', function() use ($app) { CaptchaController::postCatchaTryValidate($app); });
当我用 Angular 复制 VisualCaptcha 的示例并 运行 代码时,它显示了错误的 url 调用(错误是因为我的 SlimPHP Api 位于不同的位置)。所以错误的 url 调用看起来像这样:
GET http://localhost/myproject/user/start/5
但是要正确调用我的 SlimPHP
Api 路由,它应该是这样的
GET http://localhost/myproject/api/captcha/start/5
那么我在哪里用 VisualCaptcha 配置 Angular 的路由???我也附上了我正确的 url 的结果,所以我认为我的后端(SlimPHP)是正常工作的,它只是配置 Angular url 在控制器是错误的。
编辑
我现在更进一步了,我发现我们可以在[=28里面设置url
=] 现在可以使用以下
正确调用我的 SlimPHP
api url
vm.captchaOptions = {
imgPath: 'vendors/visual-captcha/img/',
captcha: {
numberOfImages: 5,
url: 'api/captcha'
},
// use init callback to get captcha object
init: function ( captcha ) {
vm.captcha = captcha;
}
};
我现在遇到了不显示图像的问题。这些图像应该来自 PHP 还是来自客户端的 Angular?哪个文件夹应包含所有图像?我实际上在控制台中收到此错误消息:
HTTP "Content-Type" of "text/html" is not supported. Load of media resource http://localhost/investing/api/captcha/audio?r=353oeaysbjg failed.
我其实不想要音频,虽然它给我这个音频错误,我只是想使用图像,仅此而已。请有人帮帮我!
经过 2 天的时间,我终于让它工作了。我必须做一些代码更改。所以这里是修改列表:
首先,我在 SlimPHP
应用程序中缺少会话变量:
// Inject Session closure into app
$app->session = function() use( $app ) {
if ( $namespace = $app->request->params( 'namespace' ) ) {
$session = new \visualCaptcha\Session( 'visualcaptcha_' . $namespace );
} else {
$session = new \visualCaptcha\Session();
}
return $session;
};
然后更改 HTML 代码以使用 Bootstrap
而不是 Foundation
,还添加了 2 个按钮来检查它是否已填充以及是否有效:
<div class="form-group">
<label class="control-label col-sm-5">Visual Captcha Messages</label>
<div class="col-sm-7" id="status-message">
<div class="alert" ng-class="{ 'alert-danger': (vm.valid === false), 'alert-success': (vm.valid === true) }" role="alert" ng-show="vm.status !== null">
<div ng-class="{ 'glyphicon glyphicon-remove-sign': (vm.valid === false), 'glyphicon glyphicon-ok-sign': (vm.valid === true) }" ></div>
{{ vm.status }}
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-5">Visual Captcha</label>
<div class="col-sm-7" captcha options="vm.captchaOptions"></div>
</div>
<button type="button" class="btn" ng-click="vm.isVisualCaptchaFilled()">Check if visualCaptcha is filled</button>
<button type="button" class="btn" ng-click="vm.isVisualCaptchaValid()">Validate Catpcha</button>
然后在我的 AngularJS
控制器中使用 Controller as vm
语法:
vm = this;
vm.captcha = {};
vm.captchaOptions = {
imgPath: 'vendors/visual-captcha/img/', // vendors folder on Angular side, only used for "refresh" and "audio" buttons
captcha: {
numberOfImages: 5,
url: 'api/captcha' // url for SlimPHP route calls
},
// use init callback to get captcha object
init: function ( captcha ) {
vm.captcha = captcha;
}
};
// vm public functions revealing
vm.isVisualCaptchaFilled = isVisualCaptchaFilled;
vm.isVisualCaptchaValid = isVisualCaptchaValid;
function isVisualCaptchaFilled() {
if ( vm.captcha.getCaptchaData().valid ) {
window.alert( 'visualCaptcha is filled!' );
} else {
window.alert( 'visualCaptcha is NOT filled!' );
}
}
function isVisualCaptchaValid() {
// we will post the captcha image field name and image field value
var postData = {
fieldName: vm.captcha.getCaptchaData().name,
fieldValue: vm.captcha.getCaptchaData().value
};
dataService.isVisualCaptchaValid(postData)
.then(function(data) {
// Show success/error messages
if ( data.status === 'noCaptcha' ) {
vm.valid = false;
vm.status = 'visualCaptcha was not started!';
} else if ( data.status === 'validImage' ) {
vm.valid = true;
vm.status = 'Image was valid!';
} else if ( data.status === 'failedImage' ) {
vm.valid = false;
vm.status = 'Image was NOT valid!';
} else if ( data.status === 'validAudio' ) {
vm.valid = true;
vm.status = 'Accessibility answer was valid!';
} else if ( data.status === 'failedAudio' ) {
vm.valid = false;
vm.status = 'Accessibility answer was NOT valid!';
} else if ( data.status === 'failedPost' ) {
vm.valid = false;
vm.status = 'No visualCaptcha answer was given!';
}
})
.then(function() {
vm.captcha.refresh();
});
}
然后还必须在 SlimPHP
应用程序中重写 try
路由:
// Try to validate the captcha
// -----------------------------------------------------------------------------
$app->post( '/try', function() use( $app ) {
$captcha = new \visualCaptcha\Captcha( $app->session );
$frontendData = $captcha->getFrontendData();
$isCaptchaValid = false;
$namespace = '';
$status = '';
//POST variables, they come as a JSON encoded inside the POST
$jsonPostFields = $app->request();
$post = json_decode($jsonPostFields->getBody(), $associativeArray = true);
// Load the namespace into url params, if set
if ( isset($post['namespace']) ) {
$namespace = $post['namespace'];
}
if ( ! $frontendData ) {
$status = 'noCaptcha';
} else {
// If an image field name was submitted, try to validate it
if(isset($post["fieldName"]) && $post["fieldName"] === $frontendData['imageFieldName']) {
$imageAnswer = $post["fieldValue"];
if ( $captcha->validateImage( $imageAnswer ) ) {
$isCaptchaValid = true;
$status = 'validImage';
} else {
$status = 'failedImage';
}
} else if(isset($post["fieldName"]) && $post["fieldName"] === $frontendData['audioFieldName']) {
$audioAnswer = $post["fieldValue"];
if ( $captcha->validateAudio( $audioAnswer ) ) {
$isCaptchaValid = true;
$status = 'validAudio';
} else {
$status = 'failedAudio';
}
} else {
$status = 'failedPost';
}
$howMany = count( $captcha->getImageOptions() );
$captcha->generate( $howMany );
}
echo json_encode(array("isCaptchaValid" => $isCaptchaValid, "status" => $status));
} );
请注意,使用 dataService
仅用于测试和开发目的,您应该在保存同样位于后端的表单之前在后端验证 VisualCaptcha
。所以理论上,你只会在 Angular 中进行 1 次调用,这是通过 dataService
进行的表单保存调用,然后在服务器后端需要发生两件事(1- 验证码验证, 2-保存形式)
我还将数据修改为 post
因为我不喜欢他们完成示例的方式,我从不直接 post AngularJS SPA 应用程序中的表单,我更喜欢使用由 ng-click
调用的 dataService
,这就是为什么我必须定义自己的 postData
变量。
经过所有这些更改...它终于可以同时用于图像和音频了!!!
所以我在前端使用 AngularJS
,在后端使用 SlimPHP
和 REST url。我正在尝试使用 VisualCaptch 并且我按照 PHP 方面的说明进行操作并且它似乎在后端工作,我做了一个简单的 Angular 数据服务调用 url 和在控制台上显示它,但我根本不明白如何将它与 Angular 连接,我也下载了那部分,但是当我创建 HTML
并在 <div>
。好吧,实际上让我解释一下问题 1,Angular 试图 运行 的 url 是不正确的,但我只是不知道如何配置它,有没有选项?所以让我展示一下我到目前为止的代码...顺便说一下,我使用 Controller as vm
语法,所以你不会在我的代码中找到 $scope
。
HTML:
<div captcha options="vm.captchaOptions"></div>
AngularJS 控制器代码:
// this work as a dataService call to SlimPHP
dataService.getCaptchaHowMany().then(function(data) {
console.debug(data);
});
// where does my dataService call goes in here???
vm.captchaOptions = {
imgPath: 'vendors/visual-captcha/img/',
captcha: { numberOfImages: 5 },
init: function ( captcha ) {
vm.captcha = captcha;
}
};
SlimPHP 路线,我知道它们有效
# Captcha Routes
$app->get('/captcha/start/:howMany', function($howMany) use ($app) { CaptchaController::getCaptchaHowMany($app, $howMany); });
$app->get('/captcha/audio(/:type)', function($type = 'mp3') use ($app) { CaptchaController::getCatpchaDiskAudioStreaming($app, $type); });
$app->get('/captcha/image/:index', function($index) use ($app) { CaptchaController::getCatpchaDiskImageStreaming($app, $index); });
$app->post('/captcha/try', function() use ($app) { CaptchaController::postCatchaTryValidate($app); });
当我用 Angular 复制 VisualCaptcha 的示例并 运行 代码时,它显示了错误的 url 调用(错误是因为我的 SlimPHP Api 位于不同的位置)。所以错误的 url 调用看起来像这样:
GET http://localhost/myproject/user/start/5
但是要正确调用我的 SlimPHP
Api 路由,它应该是这样的GET http://localhost/myproject/api/captcha/start/5
那么我在哪里用 VisualCaptcha 配置 Angular 的路由???我也附上了我正确的 url 的结果,所以我认为我的后端(SlimPHP)是正常工作的,它只是配置 Angular url 在控制器是错误的。
编辑
我现在更进一步了,我发现我们可以在[=28里面设置url
=] 现在可以使用以下
SlimPHP
api url
vm.captchaOptions = {
imgPath: 'vendors/visual-captcha/img/',
captcha: {
numberOfImages: 5,
url: 'api/captcha'
},
// use init callback to get captcha object
init: function ( captcha ) {
vm.captcha = captcha;
}
};
我现在遇到了不显示图像的问题。这些图像应该来自 PHP 还是来自客户端的 Angular?哪个文件夹应包含所有图像?我实际上在控制台中收到此错误消息:
HTTP "Content-Type" of "text/html" is not supported. Load of media resource http://localhost/investing/api/captcha/audio?r=353oeaysbjg failed.
我其实不想要音频,虽然它给我这个音频错误,我只是想使用图像,仅此而已。请有人帮帮我!
经过 2 天的时间,我终于让它工作了。我必须做一些代码更改。所以这里是修改列表:
首先,我在 SlimPHP
应用程序中缺少会话变量:
// Inject Session closure into app
$app->session = function() use( $app ) {
if ( $namespace = $app->request->params( 'namespace' ) ) {
$session = new \visualCaptcha\Session( 'visualcaptcha_' . $namespace );
} else {
$session = new \visualCaptcha\Session();
}
return $session;
};
然后更改 HTML 代码以使用 Bootstrap
而不是 Foundation
,还添加了 2 个按钮来检查它是否已填充以及是否有效:
<div class="form-group">
<label class="control-label col-sm-5">Visual Captcha Messages</label>
<div class="col-sm-7" id="status-message">
<div class="alert" ng-class="{ 'alert-danger': (vm.valid === false), 'alert-success': (vm.valid === true) }" role="alert" ng-show="vm.status !== null">
<div ng-class="{ 'glyphicon glyphicon-remove-sign': (vm.valid === false), 'glyphicon glyphicon-ok-sign': (vm.valid === true) }" ></div>
{{ vm.status }}
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-5">Visual Captcha</label>
<div class="col-sm-7" captcha options="vm.captchaOptions"></div>
</div>
<button type="button" class="btn" ng-click="vm.isVisualCaptchaFilled()">Check if visualCaptcha is filled</button>
<button type="button" class="btn" ng-click="vm.isVisualCaptchaValid()">Validate Catpcha</button>
然后在我的 AngularJS
控制器中使用 Controller as vm
语法:
vm = this;
vm.captcha = {};
vm.captchaOptions = {
imgPath: 'vendors/visual-captcha/img/', // vendors folder on Angular side, only used for "refresh" and "audio" buttons
captcha: {
numberOfImages: 5,
url: 'api/captcha' // url for SlimPHP route calls
},
// use init callback to get captcha object
init: function ( captcha ) {
vm.captcha = captcha;
}
};
// vm public functions revealing
vm.isVisualCaptchaFilled = isVisualCaptchaFilled;
vm.isVisualCaptchaValid = isVisualCaptchaValid;
function isVisualCaptchaFilled() {
if ( vm.captcha.getCaptchaData().valid ) {
window.alert( 'visualCaptcha is filled!' );
} else {
window.alert( 'visualCaptcha is NOT filled!' );
}
}
function isVisualCaptchaValid() {
// we will post the captcha image field name and image field value
var postData = {
fieldName: vm.captcha.getCaptchaData().name,
fieldValue: vm.captcha.getCaptchaData().value
};
dataService.isVisualCaptchaValid(postData)
.then(function(data) {
// Show success/error messages
if ( data.status === 'noCaptcha' ) {
vm.valid = false;
vm.status = 'visualCaptcha was not started!';
} else if ( data.status === 'validImage' ) {
vm.valid = true;
vm.status = 'Image was valid!';
} else if ( data.status === 'failedImage' ) {
vm.valid = false;
vm.status = 'Image was NOT valid!';
} else if ( data.status === 'validAudio' ) {
vm.valid = true;
vm.status = 'Accessibility answer was valid!';
} else if ( data.status === 'failedAudio' ) {
vm.valid = false;
vm.status = 'Accessibility answer was NOT valid!';
} else if ( data.status === 'failedPost' ) {
vm.valid = false;
vm.status = 'No visualCaptcha answer was given!';
}
})
.then(function() {
vm.captcha.refresh();
});
}
然后还必须在 SlimPHP
应用程序中重写 try
路由:
// Try to validate the captcha
// -----------------------------------------------------------------------------
$app->post( '/try', function() use( $app ) {
$captcha = new \visualCaptcha\Captcha( $app->session );
$frontendData = $captcha->getFrontendData();
$isCaptchaValid = false;
$namespace = '';
$status = '';
//POST variables, they come as a JSON encoded inside the POST
$jsonPostFields = $app->request();
$post = json_decode($jsonPostFields->getBody(), $associativeArray = true);
// Load the namespace into url params, if set
if ( isset($post['namespace']) ) {
$namespace = $post['namespace'];
}
if ( ! $frontendData ) {
$status = 'noCaptcha';
} else {
// If an image field name was submitted, try to validate it
if(isset($post["fieldName"]) && $post["fieldName"] === $frontendData['imageFieldName']) {
$imageAnswer = $post["fieldValue"];
if ( $captcha->validateImage( $imageAnswer ) ) {
$isCaptchaValid = true;
$status = 'validImage';
} else {
$status = 'failedImage';
}
} else if(isset($post["fieldName"]) && $post["fieldName"] === $frontendData['audioFieldName']) {
$audioAnswer = $post["fieldValue"];
if ( $captcha->validateAudio( $audioAnswer ) ) {
$isCaptchaValid = true;
$status = 'validAudio';
} else {
$status = 'failedAudio';
}
} else {
$status = 'failedPost';
}
$howMany = count( $captcha->getImageOptions() );
$captcha->generate( $howMany );
}
echo json_encode(array("isCaptchaValid" => $isCaptchaValid, "status" => $status));
} );
请注意,使用 dataService
仅用于测试和开发目的,您应该在保存同样位于后端的表单之前在后端验证 VisualCaptcha
。所以理论上,你只会在 Angular 中进行 1 次调用,这是通过 dataService
进行的表单保存调用,然后在服务器后端需要发生两件事(1- 验证码验证, 2-保存形式)
我还将数据修改为 post
因为我不喜欢他们完成示例的方式,我从不直接 post AngularJS SPA 应用程序中的表单,我更喜欢使用由 ng-click
调用的 dataService
,这就是为什么我必须定义自己的 postData
变量。
经过所有这些更改...它终于可以同时用于图像和音频了!!!