Search for an element on another website - javascript

I want to create a code, which will check in another webpage source code, if the provided value (for example, in input box, activate the check by click on button) is already in option (in select menu), and show an alert if there is one.
I tried doing this in jQuery, but I never tried this before, so I failed. :/
Maybe you have an idea how to do this?

If you weren't maintaining the other site, the same origin policy would have prevented it, apart if the other site explicitly allows it by including the good CORS headers and the only solution would have been to do it server side, where you can query the server as you want.
As you maintain the other site as well, then it's easy : you just have to put the good CORS header to let your first site query it.
Here's a good tutorial on enabling cross origin requests for various server side technologies : http://enable-cors.org/
Once it's done, you simply have to query the server and analyze the page :
$.get(otherserverurl, function(html) {
var myInputVal = $('input[name=somename]', html).val();
// use the value
});

Related

dynamically generate content for a page when clicking on product

everyone. I am making a website with t-shirts. I dynamically generate preview cards for products using a JSON file but I also need to generate content for an HTML file when clicking on the card. So, when I click on it, a new HTML page opens like product.html?product_id=id. I do not understand how to check for id or this part ?prodcut_id=id, and based on id it generates content for the page. Can anyone please link some guides or good solutions, I don't understand anything :(.
It sounds like you want the user's browser to ask the server to load a particular page based on the value of a variable called product_id.
The way a browser talks to a server is an HTTP Request, about which you can learn all the basics on javascipt.info and/or MDN.
The ?product_id=id is called the 'query' part of the URL, about which you can learn more on MDN and Wikipedia.
A request that gets a page with this kind of URL from the server is usually a GET request, which is simpler and requires less security than the more common and versatile POST request type.
You may notice some of the resources talking about AJAX requests (which are used to update part of the current page without reloading the whole thing), but you won't need to worry about this since you're just trying to have the browser navigate to a new page.
Your server needs to have some code to handle any such requests, basically saying:
"If anybody sends an HTTP GET request here, look at the value of the product_id variable and compare it to my available HTML files. If there's a match, send a response with the matching file, and if there's no match, send a page that says 'Error 404'."
That's the quick overview anyway. The resources will tell you much more about the details.
There are some solutions, how you can get the parameters from the url:
Get ID from URL with jQuery
It would also makes sense to understand what is a REST Api and how to build a own one, because i think you dont have a backend at the moment.
Here some refs:
https://www.conceptatech.com/blog/difference-front-end-back-end-development
https://www.tutorialspoint.com/nodejs/nodejs_restful_api.htm

Make browser submit additional HTTP-Header if click on hyperlink

Is there a way to make the webbrowser submit additional HTTP header if the user clicks on a link?
Background: In our environment every http-request has a unique ID on the server side. See https://serverfault.com/questions/797609/apache-x-request-id-like-in-heroku
If your web application receives a http-request, I would like to know which page was the page before. The http referrer is not enough, since the user could use several tabs in his browser.
I would like to avoid to put the ugly request-id into every GET request which gets send from the browser to the server. Up to now our URLs are nice.
My prefered solution would be some JavaScript magic which adds the request-id of the current page into the next http request.
Steps in detail:
browser access URL http://example.com/search
web server receives http request with request ID 123
web server sends content of the URL to the browser (a search page). The page includes the request ID 123 somewhere
the user searches for "foobar".
the web browser submits a http request to the server and includes the previous request id somehow.
web server receives second http request (ID 456) and can access the value of the first request (ID 123) somehow.
Web server can store the relation "123 --> 456" in a database for later analysis.
My goal is to track the relations "123 --> 456". Above solution is just a strategy to get to the goal. Other strategies are welcome.
We use the web framework django. But AFAIK this does matter in this context.
the user could use several tabs in his browser
I elaborate what that means for a matching solution. The sequence of requests which come from one user does not solve the issue.
One use with several tabs:
user looks at page A in tab1
user looks at page B in tab2
user follows a link on page A to page C
user follows a link on page C to page D
user follows a link on page B (tab2) to page E.
I want to know see two sequences:
A -> C -> D
And
B -> E
The only modern 'sane' option here is to use a ServiceWorker.
A ServiceWorker can intercept HTTP requests for a domain you control and decorate it with more headers.
A ServiceWorker works 'outside' of a browser tab, and if multiple tabs are open with the same website, the same serviceworker will be used for all of them.
A full tutorial on how to accomplish that is definitely too much for this answer box, but intercepting and doing stuff with HTTP requests is a big use-case, so off-site sources will usually have this as an example.
I would say that this is kind of a bad idea. If you think you need this, maybe you can handle this in a different way. A common way to do this might be using cookies instead.
We can modify request headers using:
.setRequestHeader() method of XMLHttpRequest() object (in same or allowed origins).
Editing the headers in browser console or using some complement (it is not practical).
Performing the request from the server side e.g using CURL, wget, or some library (client->serverProxy->url with custom headers ).
It is not possible (using javascript) to change the headers sent by browser in a request like because at least now, the http content negotiation is a browser's inner capability (except in part using XMLHttpRequest in same or allowed origins).
Then, in my opinion, as #Evert said you have two practical ways (a third in fact) to achieve your goal, performing a server proxy or using cookies. Here you have a very simple way using window.localStorage:
LocalStorage example
if (!localStorage.getItem("ids")) {//<-- the place in which we store the behavior
localStorage.setItem("ids", 'somevalue')
} else {
var ids = JSON.parse(localStorage.getItem("ids"));
ids.ids.push(id);//<-- we add some value
localStorage.setItem("ids", JSON.stringify(ids));
}
Full example here: https://jsfiddle.net/hy4rzob9/ press run several times and you'll see that we store each visit, of course, in your implementation you have to replace the random number for a unique identifier of each page.
LocalStorage example with several tabs
Taking into account the update, we could store the history using also document.referrer with localStorage with something like this:
var session = Math.random();
if(!localStorage.getItem("routes")){//<-- first time
var routes = {};
routes[session] = [document.location.href];
localStorage.setItem("routes", JSON.stringify(routes))
}else{
var routes = JSON.parse(localStorage.getItem("routes"));
if(!document.referrer){
routes[session] = [document.location.href];//<-- new root
}else{
for(let ses in routes){
if(routes[ses].includes(document.referrer)){
routes[ses].push(document.location.href);
}
}
}
localStorage.setItem("routes", JSON.stringify(routes))
}
var r = JSON.parse(localStorage.getItem("routes"));
console.log(r);
Full example here https://codesandbox.io/s/qk99o4vy7q, to emulate your example open this https://qk99o4vy7q.codesandbox.io/a.html (represents A) and open in a new tab https://qk99o4vy7q.codesandbox.io/b.html (represents B), navigate in both tabs and see the console. This example won't work if we share some referrer, because we can't differentiate between referrers if we attach nothing in the URL. A -> C -> D and B -> E will work, but A -> C -> D and B -> E -> A won't.
Ping example
There is other way, that is easy but has a limitation in browser compatibility, that is using ping attribute of <a> like this:
Link to track
ping Contains a space-separated list of URLs to which, when the
hyperlink is followed, POST requests with the body PING will be sent
by the browser (in the background). Typically used for tracking.
Open the console -> network, delete all, run the snippet and click in the link, if your browser supports it, you will see that the browser send a POST request to trackPing.py (I guess doesn't exist in SO), that post is void but you could track the environmental variables such as request.environ['REMOTE_ADDR'] or something.
First of all, sorry for my english.
Edit:
After reading your edit, I realised that my answer didn't fit at all, because of the tabs.
It is not possible to modify directly the way the browser makes a get request. Knowing that, your posibilities are:
Use GET parameters. I know you try to avoid this.
As #Evert said, use ServiceWorkers. It is the cleanest way to modify a request before it leaves the browser.
The last approach (an an easy one) is similar to #Emeeus's, but instead of using localStorage, whose values are shared between tabs, you should use sessionStorage, whose values are tab-independant. Also, instead of store the entire route, you should store just a random ID. This ID will work as the identification of the chain of requests for an specific tab. Then, once your webserver returns each Request-ID for example using <meta name="request_id" content="123" /> you just need to make a request via ajax to an specific tracking endpoint and store:
chain_id (stored in sessionStorage)
request_id (stored in head > meta)
timestamp (generated in webserver)
session_id (accesible from webserver). You can avoid this, but it is still useful for checking purposes.
The request to store the route is made after you page is loaded, instead of before. This approach is quite similar to how Analytics works.
// generate an unique code and store it in sessionStorage.
if (!sessionStorage.getItem('chain_id')) {
sessionStorage.setItem('chain_id', 'a7835e0a-3ee9-e981-...');
}
// Then, if you use JQuery:
$(document).ready(function() {
$.ajax({
type: "POST",
url: 'your/tracking/endpoint/',
data: {
'chain_id': sessionStorage.getItem('chain_id'),
'request_id': document.querySelector("meta[name='request_id']").getAttribute('content'),
}
});
});
Note: It is preferable to don't use JQuery to handle tracking requests neither wait until document is fully loaded. It is just an example.
And that's all. You have the relation between user-agent, the chain, the request and the timestamp of the request, so if you need to know what request was made before or after a given one, you just need to lookup in the database using the Chain-ID and the timestamp as filters.
The django model for your requests could be.
from django.db import models
from django.contrib.sessions.models import Session
class Request(models.Model):
session = models.ForeignKey(Session)
chain_id = models.Charfield(max_length=100)
request_id = models.WhatEverField...
request_url = models.URLField(max_length=200)
created = models.DateTimeField(auto_now_add=True)
I hope it helps.
I don't know if this will help, but I think maybe Ajax will do,
like set additional header inside onclick event listener, as for request id, if it's not something that sensitive then you could use cookie for the container, or maybe something much better ...

Javascript: get data displayed from another url

I was wondering if I could get some data from another website to get it displayed on mine. The good example can be alexa.com. I need to display Alexa traffic rank and reputation in a div for example on my page, so it will be changed dynamically each time Alexa change its data.
Thank you for your help.
One way is to make an ajax request for the Alexa.com site, once you receive all the html, then you can use jquery or something to scrape it for the div you want.
It feels kinda dirty, but its an easy way to get what you want. Though this is assuming their page content isn't loaded dynamically.
Edit: See this for more info: Request external website data using jQuery ajax
yahoo yql... (instead of a php? proxy serverside script)..
I have a sneaky suspicion you do not own/control the external link site, so getting content from a different site, would fall under cross-domain security restrictions (to a modern browser).
So in order to regain 'power to the user', just use http://query.yahooapis.com/.
jQuery would not be strictly needed.
EXAMPLE 1:
Using the SQL-like command:
select * from html
where url="http://stackoverflow.com"
and xpath='//div/h3/a'
The following link will scrape SO for the newest questions (bypassing cross-domain security bull$#!7):
http://query.yahooapis.com/v1/public/yql?q=select%20title%20from%20html%20where%20url%3D%22http%3A%2F%2Fstackoverflow.com%22%20and%0A%20%20%20%20%20%20xpath%3D%27%2F%2Fdiv%2Fh3%2Fa%27%0A%20%20%20%20&format=json&callback=cbfunc
As you can see this will return a JSON array (one can also choose xml) and calling the callback-function: cbfunc.
Indeed, as a 'bonus' you also save a kitten every time you did not need to regex data out of 'tag-soup'.
Do you hear your little mad scientist inside yourself starting to giggle?
Then see this answer for more info (and don't forget it's comments for more examples).
Good Luck!

Anyway to change the "Name", or "Initiator", or add new tabs in Chrome Dev Tool's Network view?

I was wondering if there was anyway to change the name or initiator columns in the Network Tab in Chrome's Dev Tools.
The issue is that, currently I'm making a web app, and it makes tons of POST calls using jQuery. that's all fine and dandy, however, when I have 10+ calls, obviously the Network tab gets flooded with POST calls.
All calls are to the same PHP script, thus the Name column is all the same. Also, since I'm using jQuery, the initiator is set to jQuery. I was wondering if there was any way to customize this view so that I know what script is calling the POST without having to open each call and see it's properties.
It'd even be nice to see maybe a truncated version of values sent right in the list view. This way I can just look at each call and know exactly what function or script called it, or at least have a better idea, rather than 10+ entries of Name: " xxx.php".
You can add custom columns that show you the values of response headers by right clicking on the table header and selecting Response Headers > Manage Header Columns:
You can also hide columns via this right-click menu.
You can also add a query to the url you are posting to, with information about what function you are calling.
Example:
If you are posting to https://myserver.com/api it is the last part api that will be displayed as the name in the network tab.
So you can extend that url with https://myserver.com/api?whatever and you will see that in the network tab name. The back end server can and will just ignore that extra query in the url.

Hide the url in a Grails application

Is there a way to hide the url in the address bar with Grails application. Now users of the web application can see and change the request parameter values from the address bar and they see the record id in the show page.
Is there a way in Javascript or Groovy (URL Mapping) or Grails (.gsp) or HTML or Tomcat (server.xml or conf.xml or in web.xml inside application in the webapps)
ex(http://www.example.com/hide/show /) i want to avoid this url and always see (http://www.example.com) or (http://www.example.com/hide/show) without the record id
Is there a way to prevent this?
No, most browsers doesn't let you hide the address field, even if you open a new window using window.open. This is a security feature, so that one site can't easily pretend to be another.
Your application should have security checks so that one user can't access data that only another user should see. Just hiding the URL would not be safe anyway, you can easily get around that using tools built into the browser, or readily available addons.
It's part of the restful URL pattern implemented by grails.
Your best bet to hide the URL would be using an iframe within the page you want the user to see in their address bar.
Not quite sure what you mean, but I would change the default root URL mapping in UrlMappings.groovy so it looks a bit like this:
static mappings = {
"/$controller/$action?/$id?"{
constraints {
// apply constraints here
}
}
//Change it here!!!!
"/"(controller: 'controllerName', action: 'actionName')
Where 'actionName' and 'controllerName' are what you want them to be - 'hide', 'show' in your example?
Than pass all parameters via a post instead of a get, just change the <g:form> method.
You will still obviously need to implement any security checking required in the controller as stated by other posters.
Thanks,
Jim.
You can probably handle this using a variation of Post/Redirect/Get:
http://en.wikipedia.org/wiki/Post/Redirect/Get
At our Grails site we have a lot of search fields. When a user clicked a pagination link all those search fields ended up in the URL which created ugly URL:s with a higher risk that users bookmarked those addresses which could mean future problems.
We solved this by saving not only all POST but also GET with parameters into the session, redirect to GET without parameters and append those again in the controller. This not only creates nice URL:s but also a memory so that if a user goes back to an earlier menu, then selected details within that menu are redisplayed.
For your specific request to hide the id in "show/42" you can probably handle that likewise or possibly configure Grails to use "show?id=42" instead, but we don't have that requirement so I haven't looked further into that issue. Good luck!
Forgot to mention: this won't add much to security since links will still contain ids, it will only clean up the address bar.
Here's some sample code that should work. If show?id=42 is called, it saves id=42 in the session, then redirects to just show and id=42 is added to params before further processing. It does what you want, but as commented it might not always be a wise thing to do.
def show = {
if (request.method == 'GET' && !request.queryString) {
if (session[controllerName]) {
params.putAll(session[controllerName])
// Add the typical code for show here...
}
} else {
session[controllerName] = extractParams(params)
redirect(action: 'show')
return
}

Categories