I am trying to create a user login/signup on my remote app that accesses user data on Salesforce. I am doing this from javascript via Salesforce REST API. This was not working using requests straight from javascript due to CORS restrictions, so I found this example. My code is as follows:
var result = sforce.connection.login('example#provider.com', 'pass'+'securityToken');
sforce.connection.init(result.sessionId, 'https://login.salesforce.com/services/oauth2/token')
sforce.connection.remoteFunction({
url: 'https://login.salesforce.com/services/oauth2/token',
requestHeaders: {
"Authorization" : "Bearer " +__sfdcSessionId,
"Content-Type":"application/json",
"Connection":"Keep-Alive"
},
method: "GET",
onSuccess : function(response) {
console.log("Success " + response)
},
onFailure: function(response) {
console.log("Failed " + response)
}
});
When I run this code I get the following errors:
1) Refused to set unsafe header "User-Agent"
2) POST http:///services/Soap/u/31.0 404 (Not Found)
3) Remote invocation failed, due to:
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL /services/Soap/u/31.0 was not found on this server.</p>
</body></html>
status code:
Using a code editor I can see that the errors are occurring after hitting the sforce.connection.login() script and never making it to the sforce.connection.init() script in my code.
How do I resolve this issue so that I may log a user in from my remote web app and gain access to the user information within salesforce?
It seem your issue is like the one in this post
XMLHttpRequest isn't allowed to set these headers, they are being set automatically by the browser. The reason is that by manipulating these headers you might be able to trick the server into accepting a second request through the same connection, one that wouldn't go through the usual security checks - that would be a security vulnerability in the browser.
Related
I'm trying to load a cross-domain HTML page using AJAX but unless the dataType is "jsonp" I can't get a response. However using jsonp the browser is expecting a script mime type but is receiving "text/html".
My code for the request is:
$.ajax({
type: "GET",
url: "http://saskatchewan.univ-ubs.fr:8080/SASStoredProcess/do?_username=DARTIES3-2012&_password=P#ssw0rd&_program=%2FUtilisateurs%2FDARTIES3-2012%2FMon+dossier%2Fanalyse_dc&annee=2012&ind=V&_action=execute",
dataType: "jsonp",
}).success( function( data ) {
$( 'div.ajax-field' ).html( data );
});
Is there any way of avoiding using jsonp for the request? I've already tried using the crossDomain parameter but it didn't work.
If not is there any way of receiving the html content in jsonp? Currently the console is saying "unexpected <" in the jsonp reply.
jQuery Ajax Notes
Due to browser security restrictions, most Ajax requests are subject to the same origin policy; the request can not successfully retrieve data from a different domain, subdomain, port, or protocol.
Script and JSONP requests are not subject to the same origin policy restrictions.
There are some ways to overcome the cross-domain barrier:
CORS Proxy Alternatives
Ways to circumvent the same-origin policy
Breaking The Cross Domain Barrier
There are some plugins that help with cross-domain requests:
Cross Domain AJAX Request with YQL and jQuery
Cross-domain requests with jQuery.ajax
Heads up!
The best way to overcome this problem, is by creating your own proxy in the back-end, so that your proxy will point to the services in other domains, because in the back-end not exists the same origin policy restriction. But if you can't do that in back-end, then pay attention to the following tips.
**Warning!**
Using third-party proxies is not a secure practice, because they can keep track of your data, so it can be used with public information, but never with private data.
The code examples shown below use jQuery.get() and jQuery.getJSON(), both are shorthand methods of jQuery.ajax()
CORS Anywhere
2021 Update
Public demo server (cors-anywhere.herokuapp.com) will be very limited by January 2021, 31st
The demo server of CORS Anywhere (cors-anywhere.herokuapp.com) is meant to be a demo of this project. But abuse has become so common that the platform where the demo is hosted (Heroku) has asked me to shut down the server, despite efforts to counter the abuse. Downtime becomes increasingly frequent due to abuse and its popularity.
To counter this, I will make the following changes:
The rate limit will decrease from 200 per hour to 50 per hour.
By January 31st, 2021, cors-anywhere.herokuapp.com will stop serving as an open proxy.
From February 1st. 2021, cors-anywhere.herokuapp.com will only serve requests after the visitor has completed a challenge: The user (developer) must visit a page at cors-anywhere.herokuapp.com to temporarily unlock the demo for their browser. This allows developers to try out the functionality, to help with deciding on self-hosting or looking for alternatives.
CORS Anywhere is a node.js proxy which adds CORS headers to the proxied request.
To use the API, just prefix the URL with the API URL. (Supports https: see github repository)
If you want to automatically enable cross-domain requests when needed, use the following snippet:
$.ajaxPrefilter( function (options) {
if (options.crossDomain && jQuery.support.cors) {
var http = (window.location.protocol === 'http:' ? 'http:' : 'https:');
options.url = http + '//cors-anywhere.herokuapp.com/' + options.url;
//options.url = "http://cors.corsproxy.io/url=" + options.url;
}
});
$.get(
'http://en.wikipedia.org/wiki/Cross-origin_resource_sharing',
function (response) {
console.log("> ", response);
$("#viewer").html(response);
});
Whatever Origin
Whatever Origin is a cross domain jsonp access. This is an open source alternative to anyorigin.com.
To fetch the data from google.com, you can use this snippet:
// It is good specify the charset you expect.
// You can use the charset you want instead of utf-8.
// See details for scriptCharset and contentType options:
// http://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings
$.ajaxSetup({
scriptCharset: "utf-8", //or "ISO-8859-1"
contentType: "application/json; charset=utf-8"
});
$.getJSON('http://whateverorigin.org/get?url=' +
encodeURIComponent('http://google.com') + '&callback=?',
function (data) {
console.log("> ", data);
//If the expected response is text/plain
$("#viewer").html(data.contents);
//If the expected response is JSON
//var response = $.parseJSON(data.contents);
});
CORS Proxy
CORS Proxy is a simple node.js proxy to enable CORS request for any website.
It allows javascript code on your site to access resources on other domains that would normally be blocked due to the same-origin policy.
CORS-Proxy gr2m (archived)
CORS-Proxy rmadhuram
How does it work?
CORS Proxy takes advantage of Cross-Origin Resource Sharing, which is a feature that was added along with HTML 5. Servers can specify that they want browsers to allow other websites to request resources they host. CORS Proxy is simply an HTTP Proxy that adds a header to responses saying "anyone can request this".
This is another way to achieve the goal (see www.corsproxy.com). All you have to do is strip http:// and www. from the URL being proxied, and prepend the URL with www.corsproxy.com/
$.get(
'http://www.corsproxy.com/' +
'en.wikipedia.org/wiki/Cross-origin_resource_sharing',
function (response) {
console.log("> ", response);
$("#viewer").html(response);
});
The http://www.corsproxy.com/ domain now appears to be an unsafe/suspicious site. NOT RECOMMENDED TO USE.
CORS proxy browser
Recently I found this one, it involves various security oriented Cross Origin Remote Sharing utilities. But it is a black-box with Flash as backend.
You can see it in action here: CORS proxy browser
Get the source code on GitHub: koto/cors-proxy-browser
You can use Ajax-cross-origin a jQuery plugin.
With this plugin you use jQuery.ajax() cross domain. It uses Google services to achieve this:
The AJAX Cross Origin plugin use Google Apps Script as a proxy jSON
getter where jSONP is not implemented. When you set the crossOrigin
option to true, the plugin replace the original url with the Google
Apps Script address and send it as encoded url parameter. The Google
Apps Script use Google Servers resources to get the remote data, and
return it back to the client as JSONP.
It is very simple to use:
$.ajax({
crossOrigin: true,
url: url,
success: function(data) {
console.log(data);
}
});
You can read more here:
http://www.ajax-cross-origin.com/
If the external site doesn't support JSONP or CORS, your only option is to use a proxy.
Build a script on your server that requests that content, then use jQuery ajax to hit the script on your server.
Just put this in the header of your PHP Page and it ill work without API:
header('Access-Control-Allow-Origin: *'); //allow everybody
or
header('Access-Control-Allow-Origin: http://codesheet.org'); //allow just one domain
or
$http_origin = $_SERVER['HTTP_ORIGIN']; //allow multiple domains
$allowed_domains = array(
'http://codesheet.org',
'http://stackoverflow.com'
);
if (in_array($http_origin, $allowed_domains))
{
header("Access-Control-Allow-Origin: $http_origin");
}
I'm posting this in case someone faces the same problem I am facing right now. I've got a Zebra thermal printer, equipped with the ZebraNet print server, which offers a HTML-based user interface for editing multiple settings, seeing the printer's current status, etc. I need to get the status of the printer, which is displayed in one of those html pages, offered by the ZebraNet server and, for example, alert() a message to the user in the browser. This means that I have to get that html page in Javascript first. Although the printer is within the LAN of the user's PC, that Same Origin Policy is still staying firmly in my way. I tried JSONP, but the server returns html and I haven't found a way to modify its functionality (if I could, I would have already set the magic header Access-control-allow-origin: *). So I decided to write a small console app in C#. It has to be run as Admin to work properly, otherwise it trolls :D an exception. Here is some code:
// Create a listener.
HttpListener listener = new HttpListener();
// Add the prefixes.
//foreach (string s in prefixes)
//{
// listener.Prefixes.Add(s);
//}
listener.Prefixes.Add("http://*:1234/"); // accept connections from everywhere,
//because the printer is accessible only within the LAN (no portforwarding)
listener.Start();
Console.WriteLine("Listening...");
// Note: The GetContext method blocks while waiting for a request.
HttpListenerContext context;
string urlForRequest = "";
HttpWebRequest requestForPage = null;
HttpWebResponse responseForPage = null;
string responseForPageAsString = "";
while (true)
{
context = listener.GetContext();
HttpListenerRequest request = context.Request;
urlForRequest = request.RawUrl.Substring(1, request.RawUrl.Length - 1); // remove the slash, which separates the portNumber from the arg sent
Console.WriteLine(urlForRequest);
//Request for the html page:
requestForPage = (HttpWebRequest)WebRequest.Create(urlForRequest);
responseForPage = (HttpWebResponse)requestForPage.GetResponse();
responseForPageAsString = new StreamReader(responseForPage.GetResponseStream()).ReadToEnd();
// Obtain a response object.
HttpListenerResponse response = context.Response;
// Send back the response.
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseForPageAsString);
// Get a response stream and write the response to it.
response.ContentLength64 = buffer.Length;
response.AddHeader("Access-Control-Allow-Origin", "*"); // the magic header in action ;-D
System.IO.Stream output = response.OutputStream;
output.Write(buffer, 0, buffer.Length);
// You must close the output stream.
output.Close();
//listener.Stop();
All the user needs to do is run that console app as Admin. I know it is way too ... frustrating and complicated, but it is sort of a workaround to the Domain Policy problem in case you cannot modify the server in any way.
edit: from js I make a simple ajax call:
$.ajax({
type: 'POST',
url: 'http://LAN_IP:1234/http://google.com',
success: function (data) {
console.log("Success: " + data);
},
error: function (e) {
alert("Error: " + e);
console.log("Error: " + e);
}
});
The html of the requested page is returned and stored in the data variable.
To get the data form external site by passing using a local proxy as suggested by jherax you can create a php page that fetches the content for you from respective external url and than send a get request to that php page.
var req = new XMLHttpRequest();
req.open('GET', 'http://localhost/get_url_content.php',false);
if(req.status == 200) {
alert(req.responseText);
}
as a php proxy you can use https://github.com/cowboy/php-simple-proxy
Your URL doesn't work these days, but your code can be updated with this working solution:
var url = "http://saskatchewan.univ-ubs.fr:8080/SASStoredProcess/do?_username=DARTIES3-2012&_password=P#ssw0rd&_program=%2FUtilisateurs%2FDARTIES3-2012%2FMon+dossier%2Fanalyse_dc&annee=2012&ind=V&_action=execute";
url = 'https://google.com'; // TEST URL
$.get("https://images"+~~(Math.random()*33)+"-focus-opensocial.googleusercontent.com/gadgets/proxy?container=none&url=" + encodeURI(url), function(data) {
$('div.ajax-field').html(data);
});
<div class="ajax-field"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
You need CORS proxy which proxies your request from your browser to requested service with appropriate CORS headers. List of such services are in code snippet below. You can also run provided code snippet to see ping to such services from your location.
$('li').each(function() {
var self = this;
ping($(this).text()).then(function(delta) {
console.log($(self).text(), delta, ' ms');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/jdfreder/pingjs/c2190a3649759f2bd8569a72ae2b597b2546c871/ping.js"></script>
<ul>
<li>https://crossorigin.me/</li>
<li>https://cors-anywhere.herokuapp.com/</li>
<li>http://cors.io/</li>
<li>https://cors.5apps.com/?uri=</li>
<li>http://whateverorigin.org/get?url=</li>
<li>https://anyorigin.com/get?url=</li>
<li>http://corsproxy.nodester.com/?src=</li>
<li>https://jsonp.afeld.me/?url=</li>
<li>http://benalman.com/code/projects/php-simple-proxy/ba-simple-proxy.php?url=</li>
</ul>
Figured it out.
Used this instead.
$('.div_class').load('http://en.wikipedia.org/wiki/Cross-origin_resource_sharing #toctitle');
My objective is to check whether a URL is valid or not from client side. I tried the following things:
1. Tried using a ajax request using dataType as JSON. - Got the Cross-Origin Request Blocked error.
2. Tried using the JSONP as datatype. - Worked fine for some websites like google.com but it cribed for others like facebook.com
Got the error like "Refused to execute script from
FaceBook
callback=jQuery32107833494968122849_1505110738710&_=1505110738711'
because its MIME type
('text/html') is not executable, and strict MIME type checking is enabled."
Is there any workaround for this. I just want to make sure that the URL is valid irrespective of the content in the response.
Following is the code I wrote:
<html>
<body>
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js">
</script>
<script>
function CallPageMethod() {
$.ajax({
type: "GET",
url: "https://www.google.com/",
dataType: "jsonp",
success: function (data, textStatus, xhr) {
alert("Success");
},
error: function (data, textStatus, xhr) {
if (data.status === 200) {
alert("Finally I am done")
} else {
alert("Error");
}
},
});
}
</script>
<Button onclick="CallPageMethod()">Test URL</Button>
</body>
</html>
Any Suggestions or any alternative approach that I should follow to resolve this issue?
Not properly, but Most sites have a favicon.ico either from the site directly or provided from the hosting company for the site if it is a 404 image.
<img src="https://www.google.com/favicon.ico"
onload="alert('icon loaded')">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"
onload="alert('ajax loaded')"></script>
Although iframe and object do have onload events, invalid pages also trigger the event.
This would be the fastest site test I can think of ...
var img = new Image();
img.onload = function () {
alert("image width is " + img.naturalWidth + " not zero so site is valid");
}
img.src = "https://www.google.com/favicon.ico";
As for facebook, the each page uses resources from another url, iframes are blocked as well as scripts. You would need to make the request from a server to test if a page existed.
You're best off writing a proxy on your server so:
Client hits your server with the URL you want to check
Your server makes the request to that URL and gets a response (or not)
Server returns status code to the client
This way will avoid the CORS issues you're having to navigate and will allow you to set any HTTP headers you need to.
I have developed a Restfull application and I'd like to add another web application to consume its services so I make this Ajax call :
$.ajax({
type: "Post",
async: false,
url: "ip_adress/Inviter/api/Account/Register",
data: donne,
headers: { "Access-Control-Allow-Origin:": "*"},
success: function (data) {
console.log(data);
var tab = [];
tab["username"] = username;
tab["password"] = pwd;
var isLogged = Login.CheckCredential(tab, username);
return isLogged;
},
error: function (xhr, status, error) {
console.log(xhr);
console.log(status);
console.log(error);
}
});
I get this exception :
Object {readyState: 0, status: 0, statusText: "SyntaxError: Failed to
execute 'setRequestHeader' …-Origin:' is not a valid HTTP header
field name."} error DOMException: Failed to execute 'setRequestHeader'
on 'XMLHttpRequest': 'Access-Control-Allow-Origin:' is not a valid
HTTP header field name.
So I need to know :
How can I enable the CORS in this situation?
How can I fix my code?
You can't authorize yourself like that. It's a response header; details in the specification. The server you're sending the request to has to send that header back to let the browser know it's okay to allow your page to send an ajax request to that server. There's nothing you can do in your client-side code if the server you're trying to request from doesn't allow your origin.
somehow i redirected to this question to get the solution for my Flask application. Since the server has to send the response back to the header, the CORS has to set in the server side.
In my case i was trying to send the request from
client
http://127.0.0.1:8081/
to
server
http://127.0.0.1:5051
So i set the cors policy to allow the origin in the client side
headers: { "Access-Control-Allow-Origin:": "*"},
and for the server side, flask provides library to allow the cors
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
it actually got resolved the issue
I'm trying to handle the response of a CGI script (located on a remote machine) in a PHP generated HTML page on an apache server that I'm working on.
A little background first. The user upon accessing the webpage is asked to login using username and password (htaccess). Upon login, the username and the site-code of the user in the organization is determined. For example let:
username: user
sitecode: IN88
I'm handling the CGI call in an HTML form as follows:
<form method="POST"
action="http://path/scriptName.cgi?userid=user&siteid=IN88&type=desktop">
<input type="submit" value="Create Account"></input>
<div id="result"></div>
</form>
And handling the response as follows (The script return simple text as output saying SUCCESS, if account is created, or SKIPPED, if the users account already exists):
<script>
$(function() {
$('form').submit(function(event) {
event.preventDefault();
$.ajax({
url: 'http://path/script.cgi?userid=user&siteid=IN88&type=desktop',
type: 'POST',
dataType: 'text',
beforeSend: function() {
$('#result').html("Sending Request to Server ...");
},
success: function (response) {
console.log('Success response: ' + response);
var text = "Account Registration Status: " + response;
$('#result').html(text);
},
error: function(response){
console.log('Error response: ' + response);
$('#result').html("Account Registration Status: " + response);
}
});
});
});
</script>
The error that I'm getting is:
XMLHttpRequest cannot load http://path/script.cgi?userid=user&siteid=IN88&type=desktop. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'myMachineName' is therefore not allowed access.
Now from the error, it is clear to me that there is some access issue and the server machine where the CGI script is located is not giving access to HTTP requests from the originating machine. I tried adding the following header information in the AJAX request:
'Access-Control-Allow-Origin': '*'
But this didn't work either. Any help would be greatly appreciated.
Thanks.
Your URL is incorrect. http://path/script is going to try and hit a server named path. Since your ajax code was loaded from your server (e.g. example.com), you're effectively trying to do a cross-domain request. The browser won't even bother trying to initiate an http request, it'll get rejected immediately without ever hitting the network.
For simple AJAX requests, your url can literally be just url: '/path/script?....', and the browser will fill in the http://example.com automatically, exactly as if you had <img src="kittens.jpg"> in your html.
That or you add in the name of your server, so it's url: 'http://example.com/path/etc...'
How can i insert the parsed html content into my webpage if i have only a link of the another webpage(get the html content from this webpage). I am using ajax call and i am getting the error i write the code below. And browser is not the issue
I want it as in Facebook but not in php
<script>
jQuery.support.cors = true;
$.ajax({
type:"GET",
url:"http://www.hotscripts.com/forums/javascript/3875-how-read-web-page-content-variable.html",
dataType:"html",
crossDomain:true,
beforeSend: function(xhr)
{
xhr.overrideMimeType('text/plain; charset=UTF-8');
},
success:function(data) {
alert(data);
$("body").html(data);
},
error:function(errorStatus,xhr) {
alert("Error",errorStatus,xhr);
}
});
</script>
May be your browser don't support cors.
http://caniuse.com/cors or another domain don't send back Access-Control-Allow-Origin header.
Thanks for the comments made by Quentin.
Another option is to use jSONP.
<script>
var query = "http://query.yahooapis.com/v1/public/yql?q=" +
encodeURIComponent("SELECT * FROM html WHERE url = 'http://www.hotscripts.com/forums/javascript/3875-how-read-web-page-content-variable.html'") +
"&format=json";
$.ajax({
type:"GET",
url: query,
crossDomain:true,
beforeSend: function(xhr)
{
xhr.overrideMimeType('text/plain; charset=UTF-8');
},
success:function(data) {
alert(data);
},
error:function(errorStatus,xhr) {
alert("Error",errorStatus,xhr);
}
});
</script>
Third option is to make a request through a proxy script located on your domain.
In reply to:
"i have used jQuery.support.cors=true; still there is a prob"
As I have said the server should return you the necessary headers.
If the other side does not allow it to become nothing can be done.
Check this:
http://en.wikipedia.org/wiki/Cross-origin_resource_sharing
To initiate a cross-origin request, a browser sends the request with an Origin HTTP header. The value of this header is the domain that served the page. For example, suppose a page from http://www.example-social-network.com attempts to access a user's data in online-personal-calendar.com. If the user's browser implements CORS, the following request header would be sent to online-personal-calendar.com:
Origin: http://www.example-social-network.com
If online-personal-calendar.com allows the request, it sends an Access-Control-Allow-Origin header in its response. The value of the header indicates what origin sites are allowed. For example, a response to the previous request would contain the following:
Access-Control-Allow-Origin: http://www.example-social-network.com
If the server does not allow the cross-origin request, the browser will deliver an error to example-social-network.com page instead of the online-personal-calendar.com response.
To allow access from all domains, a server can send the following response header:
Access-Control-Allow-Origin: *
This is generally not appropriate. The only case where this is appropriate is when a page or API response is considered completely public content and it is intended to be accessible to everyone, including any code on any site.
The value of "*" is special in that it does not allow requests to supply credentials, meaning HTTP authentication, client-side SSL certificates, nor does it allow cookies to be sent