Ran into an issue where I need to use GET vs POST on a form method, but GATC cookie data is not being appended to the URL correctly, because the form's data is trumping Google's GATC data (using linkByPost).
I've read up on a potential solution posted here, but seems like an insane amount of work to make GET behave. I also stumbled upon another solution here, but IE doesn't respect anything after the 'anchor' portion of the url.
Anyone have any other ideas? If I can't handle this via JS, I will have to go into the script handling the form action and massage the querystring manually (assuming that GATC data is in $_REQUEST array). FTR, GATC data is not available via the $_REQUEST array, when using get.
For future reference, in case anyone runs into the same issue, this is the solution I implemented. I lifted some code from the answer to this SO post, and combined it with the idea behind this post, where it localizes the GATC data, and adds hidden fields to the form for each one.
Resulting code:
$(document).ready(function() {
$('#formId').submit(function(e) {
try {
e.preventDefault();
var form = this;
if (typeof _gat !== 'undefined') {
_gaq.push(['_linkByPost', this]);
var pageTracker = _gat._getTrackerByName();
var url = pageTracker._getLinkerUrl(form.action);
var match = url.match(/[^=&?]+\s*=\s*[^&#]*/g);
for ( var i = match.length; i--; ) {
var spl = match[i].split("=");
var name = spl[0].replace("[]", "");
var value = spl[1];
$('<input>').attr({
type: 'hidden',
name: name,
value: value
}).appendTo(form);
}
}
setTimeout(function() { form.submit(); }, 400);
} catch (e) { form.submit(); }
});
});
You can use jQuery serialize to get the form's elements, then _getLinkerUrl to append the cross-domain tracking data
$('#formID').submit(function(e) {
var pageTracker = _gat._getTrackerByName();
var url = this.action + '?' + $(this).serialize();
url = pageTracker._getLinkerUrl(url);
if (this.target != '_blank') location.href = url;
else window.open(url);
});
Related
Here i am trying to open the file in new tab by calling ViewFile action of Doctor controller using Ajax Success which is in functionabc(this) on click of anchor tag.
Now the problem is that everything is as required but the url doesnot open in new tab.
Below is my Ajax
<script>
function abc(thisEvent) {
debugger;
var getDoCredId = $(thisEvent).attr('docCredId');
var parameter = { id: getDoCredId };
$.ajax({
url: "/Doctor/ViewFile1",
type: "get",
dataType: "html",
data: parameter,
success: function (data) {
debugger;
if (data = true) {
debugger;
var getdoctorId = $(thisEvent).attr('docCredId');
var url = "/Doctor/ViewFile/" + getdoctorId;
window.open(url, "_blank");
}
else {
debugger;
showNotification("Error", "warning");
}
}
});
}
Below is my anchor tag HTML
<a title="View Attachment" docCredId = "' + getDocCredId + '" onclick="abc(this)"><i class="btn btn-web-tbl btn-warning fa fa-eye "></i></a>
Below is code behind
public bool ViewFile1(int id)
{
var document = _doctorService.GetDoctorCredentialDetails(id);
string AttachPath = ConfigPath.DoctorCredentialsAttachmentPath;
string strFileFullPath = Path.Combine(AttachPath, document.AttachedFile);
string contentType = MimeTypes.GetMimeType(strFileFullPath);
bool checkFileInFolder = System.IO.File.Exists(strFileFullPath);
if (checkFileInFolder == true)
{
return true;
}
else
{
return false;
}
}
public ActionResult ViewFile(int id)
{
var document = _doctorService.GetDoctorCredentialDetails(id);
string AttachPath = ConfigPath.DoctorCredentialsAttachmentPath;
string strFileFullPath = Path.Combine(AttachPath, document.AttachedFile);
string contentType = MimeTypes.GetMimeType(strFileFullPath);
bool checkFileInFolder = System.IO.File.Exists(strFileFullPath);
bool filedata = System.IO.File.ReadAllBytes(strFileFullPath).Any();
byte[] filedata1 = System.IO.File.ReadAllBytes(strFileFullPath);
var cd = new System.Net.Mime.ContentDisposition
{
FileName = document.FileName,
Inline = true
};
Request.HttpContext.Response.Headers.Add("Content-Disposition", cd.ToString());
return File(filedata1, contentType);
}
Since this is too long for a regular comment, I am posting this as an answer, although it isn't directly going solve the problem because I am not able to reproduce it, but might give some insights and let you check the differences with what happens in your code as compared with this simplified example.
Calling window.open() from jQuery ajax success callback works just fine: https://codepen.io/nomaed/pen/dgezRa
I used the same pattern as you did, without your server code but using jsonplaceholder.typicode.com sample API instead.
There are some issues with the code sample that you might want to consider, even though you didn't ask for comments about it and it's not directly related to your issue (probably):
if (data = true) means data will always be true. You probably mean to do a if (data === true) if you know it's a boolean value, or if (data) if you want to accept any truthy value (true, {}, "something", 42, etc). Judging by the Java code and how you define the response format in the jQuery ajax call, it looks like you're expecting the "data" variable result be an HTML and not a boolean. You might want to try and remove the dataType: "html" row and let jQuery set the data format according to what is coming back from the server, and/or send a JSON formatted response, as in a POJO of { result: true } for a successful response. Then make sure that data.result === true to be sure that you got what you expect.
You should probably add arbitrary data to tags DOM elements the data-* attributes and if you're using jQuery, access them using the .data() selector. White adding just random attributs with string values may work, it's considered an abuse of the HTML and DOM, and the data-* attributes are there specifically for adding any data.
In the abc() function you grab the value of the attribute in the beginning (var getDoCredId = $(thisEvent).attr('docCredId');) but in the callback you're trying to get the value once more. You really don't need it since the success() callback is a closure in the scope of the abc() function and it has access to the value already, so doing var getdoctorId = $(thisEvent).attr('docCredId'); in the callback is really not needed.
I'd also suggest naming getDoCredId variable just as docCredId. Having a "get" prefix usually means that it's a getter function or a reference to some getter. Likewise, the "thisEvent" argument of the main function should probably be called "callerElement" or something like that since it's not an event, it's an actual element that you're passing directly from the DOM when calling abc(this) in the onClick event handler of the <a> anchor. This is just to make the code clearer to understand for anyone who's reading it, and for yourself when you're coming back to it several months in the future and trying to figure out what's going on :)
Try adding async: false to your Ajax request
function abc(thisEvent) {
debugger;
var getDoCredId = $(thisEvent).attr('docCredId');
var parameter = { id: getDoCredId };
$.ajax({
async: false, // <<<----------- add this
url: "/Doctor/ViewFile1",
type: "get",
dataType: "html",
data: parameter,
success: function (data) {
debugger;
if (data = true) {
debugger;
var getdoctorId = $(thisEvent).attr('docCredId');
var url = "/Doctor/ViewFile/" + getdoctorId;
window.open(url, "_blank");
}
else {
debugger;
showNotification("Error", "warning");
}
}
});
}
I would really appreciate some help on this. I have a page that shows products in a store using laravel pagination. I have filters on the page based on brands, category, and available products. for filtering the products I am using a checkbox. if a checkbox is checked I use ajax get request and send status via URL to a controller to filter available products.
status = 1 is for available products, and status = 0 is for all products.Url is looks like this:
/Collections/Newest_Items?status=1&page=2
Here is the situation. I want to know if is it possible to change the variable value in URL and regenerate the URL base on the page number and new filters dynamically? Is it a way to get the URL of the page using jquery and change the values and then change the Url with window.history.pushState("", "", URL);?
Here is my ajax:
$(document).on('click', "#only_available", function () {
if ($('#only_available').is(':checked')) {
var status = 1;
url = '/Collections/Newest_Items?status='+status;
} else {
var status = 0;
url = '/Collections/Newest_Items';
}
window.history.pushState("", "", url);
$.ajax({
url: '/Collections/Newest_Items',
type: "GET",
data: {status: status},
cash: false,
success:
function (response) {
$('#products-load').html(response);
}
});
});
});
I do this by writing the URL by myself. In this situation, I must write the URL after every filter applied to the page. this way I cant get the page the user currently in and it goes back to the first page. But what I want to achieve here is, I want to make the Url dynamically with page number the user currently on with all filters applied to it.
You can use window.location.search which will give you something like: status=1&page=2 in your example. Then you will need to parse out those variables to get the page number you're looking for.
Ok I think I understand what you are asking for. So with each unique filter event that you are firing you need to query the current url before pushstate and get the values with something like this.
For instance if someone clicks Brand then you would get the new brand variable as well as the current status and page variables to pass with ajax like this
also just POST it instead of GET
$(document).on('click', ".brand", function () {
var brand = $(this).attr('id);
//Example how to use it:
var params = parseQueryString();
var status = params["status"]);
var page = params["page"]);
// if you have more variables than this then you would add them here and make sure you pass them along to the ajax data.
url = '/Collections/Newest_Items?status='+status+'&page='+page+'&brand='+brand;
window.history.pushState("", "", url);
$.ajax({
url: '/Collections/Newest_Items',
type: "POST",
data: {status: status, page: page, brand: brand},
cash: false,
success:
function (response) {
$('#products-load').html(response);
}
});
});
var parseQueryString = function() {
var str = window.location.search;
var objURL = {};
str.replace(
new RegExp( "([^?=&]+)(=([^&]*))?", "g" ),
function( $0, $1, $2, $3 ){
objURL[ $1 ] = $3;
}
);
return objURL;
};
tnx to #CesarBielich and #Sokies I finally manage to solve the problem. they give me part of the answer but not all.I made it unique to my question:
what we need here is the path and the parameters that nested in URL. so for getting the path of the route, we must use window.location.pathname and for getting all the parameters must use window.location.search. after that, we must combine the path and params so that the URL comes out of it. then we must add the new parameter like status after that. So that all the parameters can be accessed by the controller. both the old params and the new one. this way laravel pagination knows what url to make, in the href links to other pages.
$(document).on('click', "#only_available", function () {
if ($('#only_available').is(':checked')) {
var status = 1;
} else {
var status = 0;
}
var params = window.location.search;
var path = window.location.pathname;
var old_url = path+params;
var url = old_url+'&status=' + status;
window.history.pushState("", "", url);
$.ajax({
url: url,
type: "GET",
cash: false,
success:
function (response) {
$('#products-load').html(response);
}
});
});
});
In a custom JavaScript file in Swagger-UI I was trying to access the request URL because I needed to add it to a header before I submit the request.
After looking at the source for swagger UI, I've not been able to figure out how to access the request URL.
In a my custom JavaScript file I've cheated by stealing from the DOM using:
(function() {
$(function() {
$(".submit").click(function (e) {
// doesn't work
// log(SwaggerUi.Views.OperationView.invocationUrl);
var url = $($(this).parentsUntil(".operations")[3]).find(".path")[0].innerText;
log("URL: " + url);
});
});
})();
But being this is a hack, it will not work if the route had a parameter like so: url/{param}. To find the input param and replace would be another step I would rather not take.
Am I missing some easy way that would allow me to access the request URL something along the lines of: SwaggerUi.requestUrl
Devised solution to traverse the DOM to get the information needed instead of using the information being stored by Swagger-UI.
(note: using the embedded Swagger-UI given by Swashbuckle 5.4 your mileage may vary if you use a different version of Swagger-UI)
$(".submit").click(function (e) {
var originalUrl = $($(this).parentsUntil(".operations")[3]).find(".path")[0].innerText;
log(originalUrl);
var outputUrl = "";
$($(this).parentsUntil(".operations")[3])
.find("tbody.operation-params tr:contains('path')")
.find("input")
.each(function () {
var pathParam = $(this).attr('name');
log(pathParam);
var userInput = $(this).val();
log(userInput);
outputUrl = originalUrl.replace("{" + pathParam + "}", userInput);
log(outputUrl);
});
// final requestUrl or invocationUrl
var requestUrl = $(".footer h4").html().match(/: (\/[\w-]+)/)[1] + outputUrl;
});
When Method of the senderform is POST, everything works fine. However, as soon as I change the method to GET, I don't receive anything on the server.
function ajaxSubmit(destinationElement, senderform) {
var xmlreq = new XMLHttpRequest();
var params = new FormData(senderform);
xmlreq.open(senderform.method, senderform.action, true);
if (/\/content\.php$/.test(senderform.action))
xmlreq.onreadystatechange = receiveTable;
else xmlreq.onreadystatechange = receiveText;
xmlreq.send(params);
}
I know that I could manually append key-value pairs at the end of Action address, but the problem is that I don't know which form is going to be passed with what fields.
I would prefer native javaScript if possible.
How can I send a GET request using XMLHttpRequest with key-value pairs from senderform which points to form Element (the same way as it already works for POST requests)?
First parameter is a reference to submit button, or form element itself. Second is callback function for XMLHttpRequest.
var ajaxSubmit = function(sender, callback) {
var xmlreq = new XMLHttpRequest(), params;
// look around for the sender form and key-value params
if (sender.form !== undefined)
{
params = new FormData(sender.form);
params.append(sender.name, sender.value);
sender = sender.form;
}
else params = new FormData(sender);
var actAddress = sender.action;
// append the params to the address in action attribute
if (sender.method == 'get')
{
var firstRun = true;
for (var key of params.keys())
{
if (firstRun)
{
actAddress += '?';
firstRun = false;
}
else actAddress += '&';
actAddress += key + "=" + params.get(key);
}
}
xmlreq.open(sender.method, actAddress, true);
xmlreq.onreadystatechange = callback;
if (sender.method == 'get')
xmlreq.send();
else xmlreq.send(params);
}
Therefore you can use it as
<form onsubmit="ajaxSubmit(this,callbackFx)" >
<!-- or -->
<input onclick="ajaxSubmit(this,callbackFx)" type="submit" name="" value=""/>
</form>
Are you sure the problem is not the PHP script? I see no reference that https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#send() with FormData needs POST to work, but if the PHP script takes the info from $POST or something (My PHP is rusty), the behavior would be different.
Since you can't create a useable body in a GET request (see below), then the other option is to use params in the url.
function buildGetUrlParams(baseUrl, paramsObj) {
var builtUrl = baseUrl + "?";
Object.keys(paramsObj).forEach(function(key) {
builtUrl += key + "=" + paramsObj[key] + "&";
});
return builtUrl.substr(0, builtUrl.length - 1);
}
document.getElementById('finalUrl').innerText = buildGetUrlParams('http://test.url.com', { name:'James', occupation:'web design' });
<div id="finalUrl"></div>
An HTTP GET request can contain a body, but there is no semantic meaning to that body. Which means, in simple terms, that a server doesn't have any reason to, nor have any knowledge of how, to process the body of a GET request. If it's possible to write a server that could do this, it would be bad practice as per the HTTP/1.1 specs:
if the request method does not include defined semantics for an entity-body, then the message-body SHOULD be ignored when handling the request.
And that's basically why it's not working. If you want to send any sort of data that the server is able to respond to, then you'll need to use a different HTTP method.
This answer also explains this issue.
I need to make a function in JavaScript to locate href inside the url that is given, and to return it as a string.
For example: http://stackoverflow.com/
So the function starts with: function example(url) {}
I want to find the first link inside this url that contain the words google.
In this page there is somewhere link like <a href:"http://google.com/asdasdadsa/asdada">
The function is to return the whole link as string.
So basically from what I can gather, you want to look at each link on the page and get the whole URL if it includes some string (i.e. google).
Here's a function that finds the first link matching a certain string:
function checkLinks( searchString ) {
var url;
// Go through each link
$('a').each( function ( ) {
// Check if the search string exists
if( $(this).attr('href').indexOf(searchString) != -1 ) {
url = $(this).attr('href');
// If we've found one, stop the each.
return false;
}
});
return url;
}
I've put together a jsfiddle showing an example of how this function could be used:
http://jsfiddle.net/K9KvS/1/
EDIT:
I've just seen you need to do this on a remote URL. You probably need to use AJAX to load in the code, then run this on the code you have. Unfortunately due to the same origin policy, you can't get this directly, so you'll need to run a server-side script on your server (e.g. using PHP) to load the content of the external page, then an AJAX call from your JS to pull it into your javascript.
Modified version to include an AJAX load of some code, then a find on that code:
// Create a function to do the actual search
function checkLinks( code, searchString ) {
var url;
// Search the code for all <a> tags, the loop over them
$(code).find('a').each( function ( ) {
// Check if there is a match (indexOf returns -1 if not)
if( $(this).attr('href').indexOf(searchString) != -1 ) {
// set the "url" variable to the href
url = $(this).attr('href');
// Stop looping
return false;
}
});
return url;
}
// Now, when the page loads, attach an AJAX call to a button with ID "linkchecker"
$( function ( ) {
$('#linkchecker').click( function( ) {
var code;
// Perform the AJAX call, load the data and call our function above to find "google.com"
$.get( 'load_code.php?url=http://www.google.com', function( data ) {
code = data;
alert( checkLinks( code, 'google.com' ) );
});
});
});
load_code.php would probably look something like this (probably with some error checking, etc):
<?php
$htm = file_get_contents($_GET['url']);
echo $htm;
?>
Update: Using Raw Javascript
We'll modify checkLinks from above to use raw Javascript:
function checkLinks( code, searchString )
{
var url;
// We need to create an HTML document element so we can use javascript dom functions on it.
var doc = document.createElement("html");
doc.innerHTML = code; // put the code into the document
// Get all links in the code
var links = doc.getElementsByTagName("a")
// Loop over all links
for (var i=0; i<links.length; i++) {
// Check if the search string (e.g "google.com") is found in the href of the link
if( links[i].getAttribute("href").indexOf(searchString) != -1 ) {
// Set it to the return value
url = links[i].getAttribute("href");
// stop looping
break;
}
}
return url;
}
So firstly, you need to set up the Ajax request object. The problem is this differs between browsers, so you need an unpleasant bit of code to generate it across them. The following is modified from the tiztag ajax tutorial:
function makeAJAXObject(){
var ajaxRequest; // The variable that makes Ajax possible!
try{
// Opera 8.0+, Firefox, Safari
ajaxRequest = new XMLHttpRequest();
} catch (e){
// Internet Explorer Browsers
try{
ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try{
ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e){
// Something went wrong
alert("Your browser broke!");
return false;
}
}
}
return ajaxRequest;
}
Ok, so now we've got our AJAX object, we want to get it to load a page, and tell it how to handle what we get back:
/*
* A function to load a given URL and process the code from it.
* It takes three arguments:
* php_handler The name of the PHP file that will load the code (or ASP, or whatever you choose to use)
* url The URL to be loaded.
* searchString The string to find in the links (e.g. "google.com").
*/
function load_page( php_handler, url, searchString )
{
// Get the ajax object using our function above.
window.ajax = makeAJAXObject( );
// Tell the AJAX object what to do when it's loaded the page
window.ajax.onreadystatechange = function(){
if(window.ajax.readyState == 4){ // 4 means it's loaded ok.
// For simplicity, I'll just alert this, but you would put your code to handle what to do when a match is found here.
alert(checkLinks( window.ajax.responseText, searchString ));
}
}
// Set up the variables you want to sent to your PHP page (namely, the URL of the page to load)
var queryString = "?url=" + url;
// Load the PHP script that opens the page
window.ajax.open("GET", php_handler + queryString, true);
window.ajax.send(null);
}
The final thing is to attach this to a button when the page has loaded:
window.onload = function( ) {
document.getElementById('linkchecker').onclick = function( ) {
load_page('load_page.php', 'http://www.example.com', 'google');
}
}
Please note, there's likely to be built in WinJS functions to handle some of the AJAX stuff, but I've never tried Win 8 app development, so I don't know them!