I am trying to send a form thru POST to my REST Resource (Java) and I am not able to, as my request gets sent as OPTIONS instead. I Know that the REST Resource is fine since it works perfectly while I test it with Poster Firefox.
jQuery/Ajax call:
function loadTwitter(){
arrayTweets = new Array();
var urlTwitter = "http://localhost:8081/streamingvideoservice/services/twitter/retrieveTweets";
$.ajax({
type: "POST",
url: urlTwitter,
contentType: "application/x-www-form-urlencoded",
//accept: "application/json",
data: $("form#mapForm").serialize(),
dataType: "json",
async: false,
success: function (resp, status, xhr) {
$("#message").html("STATUS: " + xhr.status + " " + xhr.statusText + "\n" + resp);
$("#message").hide();
$.each(resp, function() {
$.each(this, function(i, item) {
arrayTweets.push(item);
});
});
displayTweets();
},
error: function(resp, status, xhr){
$("#message").html("ERROR: " + xhr.status + " " + xhr.statusText + "\n" + resp.e);
$("#message").show();
}
});
}
REST Resource:
#POST
#Path("/retrieveTweets")
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
#Produces("application/json")
public List<Tweet> retrieve(#FormParam("lat") Double Latitude, #FormParam("lon") Double Longitude, #FormParam("rad") Integer Radius, #FormParam("from") String From, #FormParam("to") String To) {
ArrayList<Tweet> lTweets = new ArrayList<Tweet>();
boolean status = false;
Twitter twitter = new TwitterFactory().getInstance();
AccessToken accessToken = new AccessToken(TwitterInterface.ACCESS_TOKEN, TwitterInterface.ACCESS_TOKEN_SECRET);
twitter.setOAuthConsumer(TwitterInterface.CONSUMER_KEY, TwitterInterface.CONSUMER_SECRET);
twitter.setOAuthAccessToken(accessToken);
try {
Query query = new Query("");
GeoLocation geo = new GeoLocation(Latitude, Longitude);
query.setGeoCode(geo, Radius, Query.KILOMETERS);
query.setCount(100);
query.setSince(From);
query.setUntil(To);
QueryResult result;
result = twitter.search(query);
List<Status> tweets = result.getTweets();
for (Status tweet : tweets) {
System.out.println("#" + tweet.getUser().getScreenName() + " - " + tweet.getText() + " - " + tweet.getCreatedAt());
Tweet t = new Tweet();
t.setUser(tweet.getUser().getScreenName());
t.setText(tweet.getText());
lTweets.add(t);
}
}
catch (TwitterException te) {
te.printStackTrace();
System.out.println("Failed to search tweets: " + te.getMessage());
System.exit(-1);
}
return lTweets;
}
I am using jQuery 1.9.1 and hosting the Resource on Tomcat 6.
Any help is appreciated.
Thanks in advance.
You appear to be making a cross origin Ajax request. This requires that the server provides an Access-Control-Allow-Origin header to grant permission to the site hosting the page containing the JS to read the data.
Something about the request (probably the X-Requested-With header that jQuery adds to Ajax requests) is triggering a preflight request which uses an OPTIONS request to ask the server for permission before making the main request.
You will need to configure the server to provide an OPTIONS response with suitable Access Control headers as per the CORS specification (linked above).
Solved it with a GET instead and passing the parameters in the URI.
Related
I am writing a script that does a lookup for a domain, then will iterate through each IP for reachability.
For instance, if you look up google.com, there are 6 IPs. I want to go to google.com, but force it to use each IP, returning 6 different results.
I have everything, except how do I use the IP? If I just specify the IP, it fails as the servers don't respond to the IP - site is bound to the domain.
I am using npm & electron if that helps...
function checkConnection(myIP, myPort, myDomain) {
var isAccessible = null;
var url = "https://" + myDomain + ":" + myPort;
console.log(myDomain + " check at "+ url);
$.ajax({
url: url,
type: "get",
cache: false,
dataType: 'text',
timeout : 1500,
complete : function(xhr, responseText, thrownError) {
if(xhr.status != "404") {
isAccessible = true;
console.log(myDomain + " check at "+ url + " passed");
console.log(xhr);
return true;
}
else {
isAccessible = false;
console.log(myDomain + " check at "+ url + " failed");
console.log(xhr);
return false;
}
}
});
}
I have a browser action I've implemented it as an AddOn.
I'm testing my construction of the AddOn within my domain
between two machines as server and a client.
I'm stuck at AJAX failing with status code 0.
I set up Apache to enable CORS to make sure that the code is behaving as expected.
I added this line to the apache config and enabled headers:
Header set Access-Control-Allow-Origin "*"
The javascript code: UPDATED
function sendData(data){
var requestdata = 'data1=one&data2=two&data3=three';
var xhr = new XMLHttpRequest();
xhr.open("POST","http://server/test/test.php");
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.onloadstart = function(){
console.log("Onload status: " + xhr.status);
}
xhr.onerror = function(ev) {
console.log("OnError Status: " + xhr.status + ", Loaded: " + ev.loaded + ", Total: " + ev.total);
}
xhr.onreadystatechange = function() {
console.log(xhr.status);
if (xhr.status !== 200){
console.log("Failure :( + Status: " + xhr.status);
//console.log(requestdata);
console.log("Ready State: " + xhr.readyState + ", Status: " + xhr.status +", Response Text: " + xhr.responseText);
} else {
alert("Success!");
}
}
xhr.send(requestdata);
}
test.php
<?php
require '../lib/Database.php';
error_reporting(E_ALL);
$db = new Database('test');
var_dump($db);
json_encode($_POST);
?>
Have I done this AJAX implementation correctly?
If I have, and I have made adjustments for CORS, why is it failing with status code 0?
UPDATE
This is an AddOn I am testing in Firefox.
From the "matches" parameter in manifest.json, navigating to the page in question retrieves data from the page using Vanilla JS on the DOM.
The collected data is held in an object.
The data object is delivered
This is a picture of what's returned in the browser:
UPDATE2
I replaced the POST url with http://httpbin.org/post to see if the data is going anywhere. Nope.
I have mixed content error, on web site used both http and https protocols.
Here's the error from Chrome console:
Mixed Content: The page at 'https://www.amazon.com/' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://www.amazon.com/../?redirect=true'. This request has been blocked; the content must be served over HTTPS.
Here's screenshot with the error: http://prntscr.com/9os5li
Was found some solution like:
Change link from "http://" to "https://" in
Blocked loading mixed active content.
Nothing helped me, because Amazon server drop it all the time when I change link in code or manual from http to https drop it and make it as http.
For example this one Link 2 I can't use here https, because of this I have mixed content error.
Here's my AJAX where I make a call:
$.ajax({
url: "//" + MWS_URL + rest_path,
data: request,
dataType: 'text',
type: 'POST',
contentType: 'application/x-www-form-urlencoded; charset=utf-8',
beforeSend: function(req) {
//req.setRequestHeader("User-Agent", "chrome extension");
req.setRequestHeader("x-amazon-user-agent", "chrome extension");
},
success: function(data){
if (onSuccess) {
onSuccess(data);
}
},
error: function(jqXHR, textStatus, errorThrown) {
if (onError) {
onError(jqXHR, textStatus);
}
}
});
setTimeout(callService, 1000);
}
Request:
requests.push(
$.get(link.URL, function (data) {
if (IsCancel()) {
return;
}
var jdata = $($.parseHTML(data));
var parser = new ProductPageParser(jdata, link.URL);
if (!parser.isValidProduct()) {
console.log(link.URL + " is not a valid product, skipped.");
link.processed = true;
return;
}
// Process associated (linked) product on this page according to user preferences.
crawlLinkedProducts(jdata, link.URL, config);
// Store product into a collection.
var product = getProductForParser(parser, link);
//product.dbRawProductURL = urlRaw;
if (product) {
products.push(product);
}
link.processed = true;
})
);
And as I have parse in parser, here's second level parser. I parsed products on main page:
$(productUrls).each(function (index, link) {
if (!link.processed) {
console.log("Download second level -> " + link.URL);
requests_2level.push(
$.post(link.URL, "", function (data) {
if (IsCancel()) {
return;
}
console.log("End download second level -> " + link.URL);
var jdata = $($.parseHTML(data));
var parser = new ProductPageParser(jdata, link.URL);
if (!parser.isValidProduct()) {
console.log(link.URL + " is not a valid product, skipped.");
link.processed = true;
return;
}
var hackUrl = "//amazon.com/o/ASIN/" + parser.getAsin();
link.URL = hackUrl;
var product = getProductForParser(parser, link);
if (product) {
products.push(product);
}
link.processed = true;
})
);
}
});
Anyone have idea how to fix this problem?
If Amazon keep redirecting you from HTTPS to HTTP then there is nothing you can do about that short of:
Complaining hard enough at Amazon that they fix it or
Using a difference service
Decide whether to use http or https and use the same on for every call.
I have a function in my Apache Cordova application to create a new list item inside a sharepoint list, and I was wondering if it was possible to add an image to this new item, this would come as an 'attachment' in the sharepoint list. My function to add a new item looks like this:
function CreateItem(Title, Description) {
var soapEnv =
"<soapenv:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " +
"xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
"<soapenv:Body>" +
"<UpdateListItems xmlns=\"http://schemas.microsoft.com/sharepoint/soap/\">" +
"<listName>LISTNAME</listName>" +
"<updates>" +
"<Batch OnError=\"Continue\">" +
"<Method ID=\"1\" Cmd=\"New\">" +
"<Field Name=\"ID\">New</Field>" +
"<Field Name=\"Title\">" + Title + "</Field>" +
"<Field Name=\"Description\">" + Description + "</Field>" +
"</Method>" +
"</Batch>" +
"</updates>" +
"</UpdateListItems>" +
"</soapenv:Body>" +
"</soapenv:Envelope>";
$.ajax({
url: "URL",
type: "POST",
dataType: "xml",
data: soapEnv,
beforeSend: function (xhr) {
xhr.setRequestHeader("SOAPAction",
"http://schemas.microsoft.com/sharepoint/soap/UpdateListItems");
},
complete: processCreateResultSuccess,
contentType: "text/xml; charset=\"utf-8\"",
error: processCreateResultError
});
}
The image is taken with the Cordova app and has the ID "image". Any thoughts?
SharePoint: AddAttachment SOAP Web Service
Yes, you can use SharePoint SOAP web services to upload an image attachment to a list. However, there are some limitations.
My demo below uses the AddAttachment action of the Lists web service. The required parameters are listed and can be modified for your own environment. The demo simply adds a text file attachment, but it works with images and other file types too. Also works with SP 2007-2013.
The limitation is that files must be encoded as base-64 for transfer within the SOAP envelope. On the client side, base-64 file encoding is not a trivial task. I've done it using the FileReader object, but that is only available in modern browsers (IE10). There might be other options with mobile devices, but I've not researched it. Alternatively, you might look at the newer REST API.
<html>
<body>
<script type='text/javascript'>
function addAttachment( ) {
var webUrl = '', // base url when list in sub site
listName = 'CustomList', // list name or guid
listItemID = '1', // list item id
fileName = 'HelloWorld.txt', // file name
attachment = 'SGVsbG8gV29ybGQ=', // base-64 encode file data "Hello Word!"
xhr, soap;
soap = (
'<?xml version="1.0" encoding="utf-8"?>'+
'<soap:Envelope '+
'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" '+
'xmlns:xsd="http://www.w3.org/2001/XMLSchema" '+
'xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">'+
'<soap:Body>'+
'<AddAttachment xmlns="http://schemas.microsoft.com/sharepoint/soap/">'+
'<listName>' + listName + '</listName>'+
'<listItemID>' + listItemID + '</listItemID>'+
'<fileName>' + fileName + '</fileName>'+
'<attachment>' + attachment + '</attachment>'+
'</AddAttachment>'+
'</soap:Body>'+
'</soap:Envelope>'
);
xhr = new XMLHttpRequest();
xhr.open( 'POST', webUrl + '/_vti_bin/Lists.asmx', true );
xhr.setRequestHeader('Content-Type', 'text/xml; charset=utf-8');
xhr.setRequestHeader('SOAPAction', 'http://schemas.microsoft.com/sharepoint/soap/AddAttachment');
xhr.onreadystatechange = function() {
if (xhr.readyState != 4) return;
// do something - returns file path or error message
console.info( xhr.status + '\n' + xhr.responseText );
}
xhr.send( soap );
}
</script>
</body>
</html>
I am developing a browser extension using crossrider.
I have added a context menu (background.js)
var ContextData;
appAPI.contextMenu.add("key1", "Send Data To Server", function (data) {
var ContextData = 'pageUrl: ' + data.pageUrl + '\r\n' +
'linkUrl: ' + data.linkUrl + '\r\n' +
'selectedText:' + data.selectedText + '\r\n' +
'srcUrl:' + data.srcUrl;
}, ["all"]);
On user click I want to send ContextData to extension.js. At extension.js some function will receive the data and send it to my server (A Rest API which will accept the data).
To send data to the server I have tested this and it works fine (code sample in extension.js)
appAPI.ready(function($) {
var dataToSend =="test data";
appAPI.request.post({
url: 'REST API URL',
postData: dataToSend,
onSuccess: function(response, additionalInfo) {
var details = {};
details.response = response;
},
onFailure: function(httpCode) {
// alert('POST:: Request failed. HTTP Code: ' + httpCode);
}
});
});
How can I write a function to accept ContextData from background.js and assign it to dataToSend in extension.js?
#Neel If I understand your requirements correctly, #Rob is essentially correct though a little clarification may help
By design/architecture, the extension.js code runs on each HTML page i.e. a separate extension.js instance is run for each URL that loads. In contrast, the context menu runs at the browser level (not HTML page) and is hence correctly coded in background.js file. However, the background.js code does not have direct access to the extension.js instance code running on the HTML page in the active tab and must therefore communicate the data via messaging. (For more information about scopes, see Scopes Overview)
Obviously, a user clicks the context menu item on the active tab (i.e. the page showing the HTML page being viewed); hence, once the ContextData string is created, you can use appAPI.message.toActiveTab to send the string to the extension.js instance running on the page/tab where the the context menu item was clicked.
This being the case, using your code example you can achieve this goal as follows:
background.js:
appAPI.ready(function($) {
var ContextData;
appAPI.contextMenu.add("key1", "Send Data To Server", function (data) {
var ContextData = 'pageUrl: ' + data.pageUrl + '\r\n' +
'linkUrl: ' + data.linkUrl + '\r\n' +
'selectedText:' + data.selectedText + '\r\n' +
'srcUrl:' + data.srcUrl;
appAPI.message.toActiveTab({type:'dataToSend', data: ContextData});
}, ["all"]);
});
extension.js:
appAPI.ready(function($) {
var dataToSend =="test data";
appAPI.message.addListener(function(msg) {
if (msg.type === 'dataToSend') {
appAPI.request.post({
url: 'REST API URL',
postData: dataToSend,
onSuccess: function(response, additionalInfo) {
var details = {};
details.response = response;
},
onFailure: function(httpCode) {
// alert('POST:: Request failed. HTTP Code: ' + httpCode);
}
});
}
});
});
[Disclaimer: I am a Crossrider employee]