am trying to validate the recaptcha using some js code but am getting some permission Errors "Access is Denied"
Is it possible to achieve the validation using the javascript validation code alongside ajax across multiple browsers.
<script type="text/javascript">
$(document).ready(function() {
Recaptcha.create("var_public_key", recaptchadiv, {
theme: "clean",
callback: Recaptcha.focus_response_field
});
});
function submitFormData() {
var urlString = "http://www.google.com/recaptcha/api/verify";
var params = encodeURI("remoteip=" + $("#userIp").val() +"&privatekey=" + var_private_key + "&challenge=" + Recaptcha.get_challenge() + "&response=" +
Recaptcha.get_response());
params = encodeURI(params);
var status = document.getElementById("status");
status.className = "";
status.innerHTML = "<b>Submitting your data. Please wait...</b>";
var html = $.ajax({
type: "POST",
url: urlString + "?" + params,
async: false
}).responseText;
alert("ResponseText: " + html + ", Recaptcha.responseText: " + Recaptcha.responseText);
var result = html.split("\n")[0];
if (result == "true") {
status.innerHTML = " ";
return true;
}
else {
status.className = "GlobalErrorText";
status.innerHTML = "Your captcha is incorrect. Please try again";
Recaptcha.reload();
return false;
}
}
</script>
#Boug is right, this is called cross site ajax request, you can see this question to see if you can a find a solution Cross-site AJAX requests but....
I think putting your private key for recaptcha in javascript is a vulnerability, recaptcha should be validated on Server Side code, this question contain useful links about how to implement recaptcha in Asp.Net MVC How to implement reCaptcha for ASP.NET MVC? I used this approach and it works perfectly http://www.dotnetcurry.com/ShowArticle.aspx?ID=611&AspxAutoDetectCookieSupport=1
You are getting permission error because your ajax code is trying to access a script on a different site (google) as your script. From what I know, I dont think you can do cross site Ajax calls for security reasons
The question has already been answered. But, here's some added code that will work in ASP.NET WebForms, which enables you to make a local AJAX request to the page w/ the reCaptcha control, then do server-side captcha validation. The page's web method will return true/false.
I got this code from mindfire solutions, but added the execution of JS functions in the Ajax success callback b/c Ajax is making async callbacks.
Javascript:
<script type="text/javascript">
$(function(e) {
$("#submit").click(function() { // my button is type=button, not type=submit
// I'm using jQuery validation and want to make sure page is valid before making Ajax request
if ( $("#aspnetForm").valid() ) {
validateCaptcha(); // or validateCaptchaJson() if you want to use Json
} // end If ($("#aspnetForm").valid())
}); // end $("#submit").click()
}); // end $(function(e)
function validateCaptcha() {
// Individual string variables storing captcha values
var challengeField = $("input#recaptcha_challenge_field").val();
var responseField = $("input#recaptcha_response_field").val();
// Ajax post to page web method that will do server-side captcha validation
$.ajax({
type: "POST",
url: "page.aspx/ValidateCaptcha",
data: "recaptcha_challenge_field=" + challengeField + "&recaptcha_response_field=" + responseField,
async: false
success: function(msg) {
if(msg.d) { // Either true or false, true indicates CAPTCHA is validated successfully.
// this could hide your captcha widget
$("#recaptcha_widget_div").html(" ");
// execute some JS function upon successful captcha validation
goodCaptcha();
} else {
// execute some JS function upon failed captcha validation (like throwing up a modal indicating failed attempt)
badCaptcha();
// don't forget to reload/reset the captcha to try again
Recaptcha.reload();
}
return false;
}
});
}
function validateCaptchaJson() {
// JavaScript object storing captcha values
var captchaInfo = {
challengeValue: Recaptcha.get_challenge(),
responseValue: Recaptcha.get_response()
};
// Ajax post to page web method that will do server-side captcha validation
$.ajax({
type: "POST",
url: "page.aspx/ValidateCaptcha",
data: JSON.stringify(captchaInfo), // requires ref to JSON (http://www.JSON.org/json2.js)
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function(msg) {
if(msg.d) { // Either true or false, true indicates CAPTCHA is validated successfully.
// this could hide your captcha widget
$("#recaptcha_widget_div").html(" ");
// execute some JS function upon successful captcha validation
goodCaptcha();
} else {
// execute some JS function upon failed captcha validation (like throwing up a modal indicating failed attempt)
badCaptcha();
// don't forget to reload/reset the captcha to try again
Recaptcha.reload();
}
return false;
}
});
}
</script>
Page's Web Method (VB.NET):
<WebMethod()> _
Public Shared Function ValidateCaptcha(ByVal challengeValue As String, ByVal responseValue As String) As Boolean
' IDEA: Get Private key of the CAPTCHA from Web.config file.
Dim captchaValidtor As New Recaptcha.RecaptchaValidator() With { _
.PrivateKey = "your_private_key_goes_here", _
.RemoteIP = HttpContext.Current.Request.UserHostAddress, _
.Challenge = challengeValue, _
.Response = responseValue _
}
' Send data about captcha validation to reCAPTCHA site.
Dim recaptchaResponse As Recaptcha.RecaptchaResponse = captchaValidtor.Validate()
' Get boolean value about Captcha success / failure.
Return recaptchaResponse.IsValid
End Function
Related
I have the following code in my view :
<script type="text/javascript">
function OnCancelClick(e)
{
var jobId = e;
var flag = confirm('You are about to cancel job : ' + jobId + '. Are you sure you want to cancel this job?');
if (flag) {
$.ajax({
url: '/job/CancelJob',
type: 'POST',
data: { jobId: jobId },
dataType: 'html',
success: function (result) { alert('Job ' + jobId + ' was cancelled.'); document.location = "#Url.Action("Index", "Job")"; },
error: function () { alert('Something went wrong. Check the log for more information.'); }
});
}
return false;
}
</script>
In my view I also have :
<input type="submit" id="cancelButton" value="Cancel" onclick="javascript: return OnCancelClick(#Model.Id);" />
In my controller I have :
[HttpPost]
public ActionResult CancelJob(int jobId)
{
try
{
logger.LogInfo(string.Format("<start> Cancel-button clicked for job : {0}", jobId), jobId);
JobCommandService.ChangeStatus(jobId, 6);
logger.LogInfo(string.Format("<end> Cancel-button clicked for job : {0}", jobId), jobId);
return RedirectToAction("Index", "Job");
}
catch (Exception ex)
{
logger.LogError(ex.Message, ex, jobId);
Response.StatusCode = (int)HttpStatusCode.InternalServerError;
return Json(new { Success = false, Message = ex.Message });
}
}
When I run this in my VS2012 it works just fine.
When I deploy it to the server, I'm getting the message that something went wrong.
In my logging there is no trace of the button being clicked.
As per your comment, when deployed your app is installed in accindigoapps.blabla.lok/jobmonitor.
However your script has the url hardcoded as url: '/job/CancelJob'. That will mean:
when you are debugging from VS your script will work because the request is being sent to a url like http://localhost:XXX/job/CancelJob
however in production, the request will be sent to http://accindigoapps.blabla.lok/job/CancelJob, missing the jobmonitor part.
You need a way to inform your JS code about the base url of your application:
You could generate the Url in a Razor view using Url.Action("CancelJob","job") and pass that Url into your javascript code.
Another option would be to use Url.Content("~/") in some javascript of your base layout. That helper Url.Content("~/") will return only your application folder, / in your dev environment and /jobmonitor/ when deployed. That way you will have your app root-relative url available to any script, so you can use it to build root-relative urls as you were doing in your script:
<script>
var myApp = {};
myApp.BaseUrl = '#Url.Content("~/")';
</script>
//Some other script like yours would be able to keep using root-relative urls as:
$.ajax({
url: myApp.BaseUrl + 'job/CancelJob',
...
If you prefer to generate full urls, you could follow a similar approach. Have a look at this question
Hope it helps!
So, I have done this before and made many many ajax calls
For some reason this one doesn't work =(
What do I need to change to get this one to work?
Previously I had an internal server error 500, but after pasting some working code and renaming methods to shorter names finally it changed over to this error of Unknown web method.
Setup
I am using jQuery to make Ajax calls to WebMethods in my Codebehind for my ASP.NET page.
Here is my C# WebMethod
[WebMethod(EnableSession = true)]
[ScriptMethod]
public string viewApps(string foo)
{
string x = "";
//130 lines of useful code.
x = "0";
return x;
}
Here is the Javascript/jQuery doing the ajax call. It is in side a with all my other ajax calls. The other ones work. This one does not. It triggered by an onclick event in the html.
function viewApps() {
var food = "hamburger";
$.ajax(
{
//send selected makes
type: "POST",
url: "MassUpdater.aspx/viewApps",
dataType: "json",
data: "{foo:" + food + "}",
contentType: "application/json; charset=utf-8",
//process the response
//and populate the list
success: function (msg) {
//just for show
},
error: function (e) {
alert(JSON.stringify(e));
$('#result').innerHTML = "unavailable";
}
});
//to be uncommented later when functionality works.
// populateBrakeConfigs();
// populateBedConfigs();
// populateBodyStyleConfigs();
// populateSpringConfigs();
// populateSteeringConfigs();
// populateWheeleBase();
// populateTransmission();
// populateDriveTypes();
function populateBrakeConfigs() { }
function populateBedConfigs() { }
function populateBodyStyleConfigs() { }
function populateSpringConfigs() { }
function populateSteeringConfigs() { }
function populateWheeleBase() { }
function populateTransmission() { }
function populateDriveTypes() { }
}
The ajax error looks like this:
I am also willing to provide any additional code or information about my project upon request.
The answer unfortunately is that somehow the static keyword got left out of the WebMethod, therefore the ajax call cannot find it.
I know this is duplicate but I could not get reliable solution(for asp.net web).
I just want to redirect to the login page if session expires.
I have tried following:
1. using jquery status code
$.ajax({
type: "POST",
url: "stream.asmx/SomeMethod",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
//success msg
},
error: function (request, status, error) {
if (status = 403) {
location.href = 'login.aspx';
}
}
});
Problem: this returns same status code(403) for other errors too, which I only expect for session timeout.
2. Sending json message whether session expired
code behind:
if (!object.Equals(HttpContext.Current.Session["User"], null))
{
Id = int.Parse(HttpContext.Current.Session["User"].ToString());
}
else
{
result = from row in dtscrab.AsEnumerable()
select new
{
redirectUrl = "login.aspx",
isRedirect = true
};
}
on $.ajax success:
success: function (msg) {
if (msg.d[0].isRedirect) {
window.location.href = msg.d[0].redirectUrl;
}
else {
//load containt
}
}
Problem: It's somehow desn't invoke ajax success line if session expires(it does return correct json). And even this is not a proper way if I have many number of ajax request in the page(should be handled globally).
However, I saw this post which is really good soltion but it's for mvc using AuthorizeAttribute: handling-session-timeout-in-ajax-calls
So, Is there I can use same concept used in mvc using AuthorizeAttribute in asp.net web api? If not, how I can troubleshoot those issue which I'm facing (any of above two mentioned)?
A 403 status code is going to cause jQuery to call the failure method. Keep the same code behind from your second try, but move the redirect handler to the failure method instead of the success method. In the success method, treat it as you normally would.
Problem:
I had same problem in my Razor MVC Application throwing exceptions while ajax calls made when session timed out.
The way I have managed to get this issue sorted is by monitoring each ajax requests by using a simple light weight Action Method (RAZOR MVC) returning a bool variable whether the Request is Authenticated or not. Please find the code below..
Layout/Master Page / Script file:
<script>
var AuthenticationUrl = '/Home/GetRequestAuthentication';
var RedirectUrl = '/Account/Logon';
function SetAuthenticationURL(url) {
AuthenticationUrl = url;
}
function RedirectToLoginPage() {
window.location = RedirectUrl;
}
$(document).ajaxStart(function () {
$.ajax({
url: AuthenticationUrl,
type: "GET",
success: function (result) {
if (result == false) {
alert("Your Session has expired.Please wait while redirecting you to login page.");
setTimeout('RedirectToLoginPage()', 1000);
}
},
error: function (data) { debugger; }
});
})
Then in Home Controller/Server side you need a method to verify the request and return the boolean variable..
public ActionResult GetAuthentication ( )
{
return Json(Request.IsAuthenticated, JsonRequestBehavior.AllowGet);
}
This will validate each ajax request and if the session got expired for any ajax request, it will alert the user with a message and redirect the user to the login page.
I would also suggest not to use standard Alert to Alert. User some Tool tip kind of formatted div Alerts. Standard JS Alerts might force the user to click OK before redirection.
Hope it helps.. :)
Thanks,
Riyaz
Finally, I ended up following.
public class IsAuthorizedAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
var sessions = filterContext.HttpContext.Session;
if (sessions["User"] != null)
{
return;
}
else
{
filterContext.Result = new JsonResult
{
Data = new
{
status = "401"
},
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
//xhr status code 401 to redirect
filterContext.HttpContext.Response.StatusCode = 401;
return;
}
}
var session = filterContext.HttpContext.Session;
if (session["User"] != null)
return;
//Redirect to login page.
var redirectTarget = new RouteValueDictionary { { "action", "LogOn" }, { "controller", "Account" } };
filterContext.Result = new RedirectToRouteResult(redirectTarget);
}
}
Handling client side
<script type="text/javascript">
$(document).ajaxComplete(
function (event, xhr, settings) {
if (xhr.status == 401) {
window.location.href = "/Account/LogOn";
}
});
</script>
you can set session time out expire warning some thing like ....
<script type="text/javascript">
//get a hold of the timers
var iddleTimeoutWarning = null;
var iddleTimeout = null;
//this function will automatically be called by ASP.NET AJAX when page is loaded and partial postbacks complete
function pageLoad() {
//clear out any old timers from previous postbacks
if (iddleTimeoutWarning != null)
clearTimeout(iddleTimeoutWarning);
if (iddleTimeout != null)
clearTimeout(iddleTimeout);
//read time from web.config
var millisecTimeOutWarning = <%= int.Parse(System.Configuration.ConfigurationManager.AppSettings["SessionTimeoutWarning"]) * 60 * 1000 %>;
var millisecTimeOut = <%= int.Parse(System.Configuration.ConfigurationManager.AppSettings["SessionTimeout"]) * 60 * 1000 %>;
//set a timeout to display warning if user has been inactive
iddleTimeoutWarning = setTimeout("DisplayIddleWarning()", millisecTimeOutWarning);
iddleTimeout = setTimeout("TimeoutPage()", millisecTimeOut);
}
function DisplayIddleWarning() {
alert("Your session is about to expire due to inactivity.");
}
function TimeoutPage() {
//refresh page for this sample, we could redirect to another page that has code to clear out session variables
location.reload();
}
4xx are HTTP error status codes and would cause jquery to execute the onFailure callback.
Also, beware of using 3xx for redirects when you want to process the payload. Internet Explorer, in my experience, just does a redirect (without looking at the payload) when a 3xx status code is returned.
I'd say, throw a 403 and handle the situation. To the client 403 implies the resource access is forbidden. There can be multiple reasons, which is OK I guess.
For those using a ScriptManager, you can easily check for ajax request and then redirect with the following code:
private void AjaxRedirect(string url)
{
Response.StatusCode = 200;
Response.RedirectLocation = url;
Response.Write("<html></html>");
Response.End();
}
Then check for request type and redirect accordingly (using routes here):
if (ScriptManager.GetCurrent(Page).IsInAsyncPostBack)
{
var redirectUrl = RouteTable.Routes.GetVirtualPath(null, "Default", null).VirtualPath;
AjaxRedirect(redirectUrl);
}
else
{
Response.RedirectToRoute("Default");
}
The "Default" route is a route defined in the routes collection:
routes.MapPageRouteWithName("Default", "", "~/default.aspx");
If you prefer, instead of using ScriptManager for ajax request check, you can use:
if (Request.Headers["X-Requested-With"] == "XMLHttpRequest") {
code here...
}
I am lazy loading snippets of html on our page in order to improve performance. jQuery's load method does not provide access to the full ajax api (things like error callbacks) so I created a more robust version of it.
I am calling this method 3-5 times per page on just about every page load and am logging when there is some sort of error with ajax call. What I am finding is that about 0.3% of the time the ajax calls are failing the majority of the failures are in firefox 3.6. I am using jQuery 1.5.1 with ASP.NET server side. The 'errorThrown' parameter of the error callback reads:
[Exception... "Component returned failure code: 0x80040111 (NS_ERROR_NOT_AVAILABLE) [nsIXMLHttpRequest.getAllResponseHeaders]" nsresult: "0x80040111 (NS_ERROR_NOT_AVAILABLE)"
and the jqXHR reads:
{"readyState":4,"status":0,"statusText":"error"}
I have confirmed with users that they are experienceing this problem and it's not just bots or some logging of an unexperienced error.
here is the code for my "load" widget
(function ($) {
$.fn.elfLoad = function (url, options) {
return this.each(function () {
var $elem = $(this);
options = $.extend({}, {
type: "GET",
dataType: "html",
data: "",
error: function (jqXHR, status, errorThrown) {
$elem.html('<div class="elf-missing-content centerText">Doh! Something did not go so well when trying to load this content. Please try again later.');
elf.ajax.logInfo("data: " + options.data + " errorThrown: " + errorThrown + " webmethod: " + options.url + "jqXHR: " + JSON.stringify(jqXHR),"elfLoad");
}
}, options);
options.success = function (data, status, jqXHR, responseText) {
responseText = jqXHR.responseText;
if (jqXHR.isResolved()) {
jqXHR.done(function (r) {
responseText = r;
});
$elem.html(responseText);
}
if (options.callback) {
var callbackArgs = {
responseText: responseText,
$elem: $elem,
status: status,
jqXHR: jqXHR
};
$elem.each(options.callback, [callbackArgs]);
}
}
options.url = url;
if (options.data) {
options.data = $.param(options.data, $.ajaxSettings.traditional);
options.type = "POST";
} else {
options.data = "";
}
$.ajax(options);
});
}
})(jQuery);
A call to it would look like this $('#container').elfLoad('url.aspx',{foo:'bar'});
Has anyone else had this problem? Any ideas? jQuery claims to have recently closed a ticket that looks like this in 1.5.1 but I see someone else is having a similar issue. http://bugs.jquery.com/ticket/8400
Thanks!
I ended up solving this issue by using a setTimeout for 2 seconds and retrying the request. So far this is working 100% of the time.
This is with ASP.NET Web Forms .NET 2.0 -
I have a situation that I am not sure how to fulfill all the requirements. I need to update an img source on the page if selections are made from a drop down on the same page.
Basically, the drop downs are 'options' for the item. If a selection is made (i.e. color: red) then I would update the img for the product to something like (productID_red.jpeg) IF one exists.
The problem is I don't want to do post backs and refresh the page every time a selection is made - especially if I do a check to see if the image exists before I swap out the img src for that product and the file doesn't exist so I just refreshed the entire page for nothing.
QUESTION:
So I have easily thrown some javascript together that formulates a string of the image file name based on the options selected. My question is, what options do I have to do the following:
submit the constructed image name (i.e. productID_red_large.jpg) to some where that will verify the file exists either in C# or if it is even possible in the javascript. I also have to check for different possible file types (i.e. .png, .jpg...etc.).
not do a post back and refresh the entire page
Any suggestions?
submit the constructed image name
(i.e. productID_red_large.jpg) to some
where that will verify the file exists
either in C# or if it is even possible
in the javascript. I also have to
check for different possible file
types (i.e. .png, .jpg...etc.).
not do a post back and refresh the
entire page
If you wish to not post back to the page you will want to look at $.ajax() or $.post() (which is just short hand for $.ajax() with some default options)
To handle that request you could use a Generic Http Handler.
A simple outline could work like the following:
jQuery example for the post:
$("someButton").click(function () {
//Get the image name
var imageToCheck = $("#imgFileName").val();
//construct the data to send to the handler
var dataToSend = {
fileName: imageToCheck
};
$.post("/somePath/ValidateImage.ashx", dataToSend, function (data) {
if (data === "valid") {
//Do something
} else {
//Handle error
}
}, "html");
})
Then on your asp.net side you would create an http handler that will validate that request.
public class Handler1 : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
var fileName = context.Request["fileName"];
var fullPath = Path.Combine("SomeLocalPath", fileName);
//Do something to validate the file
if (File.Exists(fullPath))
{
context.Response.Write("valid");
}
else
{
context.Response.Write("invalid");
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
Hope this helps, if I missed the mark at all on this let me know and I can revise.
We have an app of the same type, webforms .net 2, we do something similar with the following setup:
Using jQuery you can call a method in the page behind of the current page, for example, the following will trigger the AJAX call when the select box called selectBoxName changes, so your code work out the image name here and send it to the server.
$(document).ready(function () {
$('#selectBoxName').change(function (event) {
var image_name = 'calculated image name';
$.ajax({
type: "POST",
url: 'SomePage.aspx/CheckImageName',
data: "{'imageName': '" + image_name + "'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
alert(msg);
},
error: function (a, b, c) {
alert("The image could not be loaded.");
}
});
});
});
Where SomePage.aspx is the current page name, and image_name is filled with the name you have already worked out. You could replace the img src in the success and error messages, again using jQuery.
The code behind for that page would then have a method like the following, were you could just reutrn true/fase or the correct image path as a string if needed. You can even return more complex types/objects and it will automatically send back the proper JSON resposne.
[System.Web.Services.WebMethod(true)]
[System.Web.Script.Services.ScriptMethod(ResponseFormat = System.Web.Script.Services.ResponseFormat.Json)]
public static bool CheckImageName(string imageName)
{
/*
* Do some logic to check the file
if (file exists)
return true;
return false;
*/
}
As it is .net 2 app, you may need to install the AJAX Extensions:
http://www.microsoft.com/downloads/en/details.aspx?FamilyID=ca9d90fa-e8c9-42e3-aa19-08e2c027f5d6&displaylang=en
Could you not use a normal ajax call to the physical path of the image and check if it returns a 404?
Like this:
http://stackoverflow.com/questions/333634/http-head-request-in-javascript-ajax
<script type="text/javascript">
function UrlExists(url) {
var http = new XMLHttpRequest();
http.open('HEAD', url, false);
http.send();
return http.status != 404;
}
function ConstructImage() {
var e = document.getElementById("opt");
var url = '[yourpath]/' + e.value + '.jpg';
if (!UrlExists(url)) {
alert('doesnt exists');
//do stuff if doesnt exist
} else {
alert('exists');
//change img if it does
}
}
</script>
<select id="opt" onchange="ConstructImage()">
<option value="red">Red</option>
<option value="blue">Blue</option>
<option value="green">Green</option>
</select>