This question already has answers here:
How can I access and process nested objects, arrays, or JSON?
(31 answers)
Closed 6 years ago.
I am trying to consume the data source from a proxy service, and the data source has the following structure:
{
"Items": {
"ItemSection": [
{
"Food": {
"Name": "Potato Chips",
"itemID": "24501"
},
"category": "Snack",
"description": "Some description",
"available": "Shop A"
},
{
"Food": {
"Name": "Cookie",
"itemID": "24510"
},
"category": "Snack",
"description": "Some description in here.",
"available": [
"Shop A",
"Shop B"
]
},
Below is the response headers :
Status Code: 200 OK
Access-Control-Request-Method: OPTIONS, GET
Cache-Control: public, max-age=321
Content-Length: 42158
Content-Type: application/json
Date: Thu, 29 Sep 2016 20:45:49 GMT
Expires: Thu, 29 Sep 2016 20:51:11 GMT
Last-Modified: Thu, 29 Sep 2016 20:31:11 GMT
Server: Microsoft-IIS/8.5
Vary: *
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
access-control-allow-credentials: true
access-control-allow-headers: Authorization, Content-Type
access-control-allow-origin
and this is how I consume the data source with JavaScript:
function getItems() {
var uri = "proxy url goes here";
var xhr = new XMLHttpRequest();
xhr.open("GET", uri, true);
xhr.onload = function () {
var resp = JSON.parse(xhr.responseText);
showItems(resp.value);
}
xhr.send(null);
}
function showItems(item) {
var tableContent = "<tr class='ItemTitle'><td>Item Lists</td></tr>\n";
for (var i = 0; i < item.length; ++i) {
var record = item[i];
tableContent += "<tr><td>" + record.Name + "</td></tr>\n";
}
document.getElementById("showItem").innerHTML = tableContent;
}
The data source doesn't show up as I run the page, all I got is a blank page with the title Items displayed only. But if I replace the code inside xhr.onload = function() {} to this:
var version_d = document.getElementById("ItemLists");
version_d.innerHTML = xhr.responseText;
Then all data source will be displayed on the page but it just displaying a raw data source and I cannot select what I want to show on the page by using showItems function.
Here's my html page :
<!DOCTYPE html>
<html>
<head>
<title>List</title>
<link rel="stylesheet" type="text/css" href="ShowOrders.css" />
<script src="ShowOrders.js"></script>
<script>
window.onload = getItems;
</script>
</head>
<body>
<h1>Items</h1>
<table id="showItem"></table>
</body>
</html>
Why it is not working with JSON.parse ? am I using the Cross-origin resource sharing (CORS) method wrong ? How can I get it works with out using any external libraries or frameworks (pure JavaScript only) ?
resp.value
JSON.parse directly returns.the parsed object, so resp.value is undefined.
You just want
return resp;
Related
I have the following subdomains:
stream.example.com
sub.example.com
Both domains have SSL certificates and are valid.
I am using videoJS 7.6.6 which has http_streaming library.
On sub.example.com , there is a video tag which sets a dash manifest as source containing links to stream.example.com.VideoJS needs to include laravel cookies from sub.example.com when making a request to stream.example.com links but this is not happening and when i download the HAR result from developer console i see empty cookies in the request.
My VideoJS HTML
<video-js id="player" class="video-js vjs-big-play-centered">
<source src="data:application/dash+xml;charset=utf-8;base64,......." type="application/dash+xml" crossorigin="use-credentials">
</video-js>
The mainifest is valid and it contains stream.example.com urls
VideoJS
player = window.player = videojs('player', {
html5: {
hls: {
withCredentials: true
}
},
controls : true,
fluid: true,
controlBar: {
children: ['playToggle', 'volumePanel', 'currentTimeDisplay', 'timeDivider', 'durationDisplay', 'progressControl', 'liveDisplay', 'seekToLive', 'remainingTimeDisplay', 'customControlSpacer', 'playbackRateMenuButton', 'chaptersButton', 'descriptionsButton', 'subsCapsButton', 'audioTrackButton', 'settingMenuButton', 'qualitySelector','fullscreenToggle']
},
preload : 'auto',
poster : '',
});
player.hotkeys({
volumeStep: 0.1,
seekStep: 5,
alwaysCaptureHotkeys: true
});
var myplugin = window.myplugin = player.myplugin();
}(window, window.videojs));
stream.example.com has the following headers when i view a video link in a browser tab.
accept-ranges: bytes
access-control-allow-credentials: 1
access-control-allow-headers: Origin, X-Requested-With, Content-Type, Content-Length, Authorization,Range
access-control-allow-methods: GET, PUT, POST, DELETE, OPTIONS
access-control-allow-origin: https://sub.example.com
access-control-max-age: 86400
cache-control: private, max-age=18350
content-length: 69688791
content-range: bytes 0-69688790/69688791
content-type: video/mp4
I downloaded the HAR request to see how videoJS is making the request
{
"startedDateTime": "2020-03-15T07:53:57.647Z",
"time": 1.1023430000004737,
"request": {
"method": "GET",
"url": "https://stream.example.com/s/......",
"httpVersion": "",
"headers": [
{
"name": "Referer",
"value": "https://sub.example.com/"
},
{
"name": "Sec-Fetch-Dest",
"value": "empty"
},
{
"name": "User-Agent",
"value": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36"
},
{
"name": "DNT",
"value": "1"
},
{
"name": "Range",
"value": "bytes=741-2044"
}
],
"queryString": [
{
"name": "u",
"value": "....."
}
],
"cookies": [], // <-- The cookies are EMPTY
"headersSize": -1,
"bodySize": 0
},
Edit 1
I am already sharing cookies in laravel by adding the following in .env
SESSION_DOMAIN = .example.com
The cookie domain for sub.example.com show .example.com but no cookie for stream.example.com
Edit 2
The response to videojs options request for stream.example.com are shown below
HTTP/2 204 No Content
server: nginx
cache-control: no-cache, private
date: Sat, 21 Mar 2020 06:19:26 GMT
access-control-allow-origin: https://sub.example.com
access-control-allow-methods: GET, POST, HEAD, OPTIONS
access-control-allow-headers: Origin, X-Requested-With, Content-Type, Content-Length, Authorization,Range
access-control-allow-credentials: 1
access-control-max-age: 86400
set-cookie: XSRF-TOKEN=eyJpdiI6ImM4czZNVFRRbWF1emFONXlVMjBGWkE9PSIsInZhbHVlIjoiazVDMUNIR2NqXC9QVUpJdjA3S2lHQ2pKdkJFeHpZdGVodHQ5XC9nZ3JHYVQyUk50V2cxdkQrZ1wvV3ZsOEpDVUhBSiIsIm1hYyI6IjUwYjk4ZjYyZDJmNjg1ZjU4YTg2MDE5ZGNkYmZlOTk5NWVmNTE5ZTRjY2Q1YzQ0ZDI3MzEyNWQ0YmExMzVjZGIifQ%3D%3D; expires=Sat, 21-Mar-2020 10:19:26 GMT; Max-Age=14400; path=/; domain=.example.com
set-cookie: laravel_session=eyJpdiI6IkZvZk9vK2J3YVVhQ2Q4VXpTZjZXN3c9PSIsInZhbHVlIjoiNHZId3orR3dQRDRiOXVFVitKR21NU21DbnVFXC9IcFMxaDFsUXRRUG9VQkFHZnNSdVpRSFBaaHJ5cXdGZDJObUgiLCJtYWMiOiI5ZjllY2IwZjFiNzkxYWMxNTI2ZTFiZWU5OTA4YjNjNzIxZWNkMTBiZjY0ZWQzNDBkMzg5MTEzYjM2MjQ4ODk1In0%3D; path=/; domain=.example.com
x-frame-options: SAMEORIGIN
x-xss-protection: 1; mode=block
x-content-type-options: nosniff
X-Firefox-Spdy: h2
I assume you need to make the cookies valid for all subdomains, "share" them, as described how to share cookie between subdomain and domain:
if you use the following, it will be usable on both domains:
Set-Cookie: name=value; domain=example.com
Try an OPTIONS request to "url": "stream.example.com/s......" and see if you get the correct response cors headers as above? You can edit and resend the request through Firefox Developer tools.
All other look good.
Set cookies for cross origin requests
Apparently you can do this now:
const player = videojs(element, options)
player.crossOrigin('anonymous')
I'm currently using Node.js to serve a webpage that takes in user inputs which are stored on a mongodb server. The web page also displays specified or all user inputs entered. I'm trying to figure how to pass the user inputs from node.js to the <p> element.
In my node.js file I am responding with the user data as a string like so:
response.writeHead(200, {"Content-Type": "text/plain"});
response.write(stringifyMongoDBCollection(user_data_collection));
response.end();
When I do this, this re-directs the client to display the content as text/plain which I expected. The next step is to update just the content of <p>. How can I do this? I thought about re-serving the entire html content with the new populated <p> but that would make all current user inputs disappear...
The user data would be a mongodb collection array and look like this:
[ { _id: 5dda17065f7e9b64282e7291,
date: 'Sat Nov 23 2019 21:37:10 GMT-0800 (Pacific Standard Time)',
field: '127' },
{ _id: 5dda18ecf330d521a035c444,
date: 'Sat Nov 23 2019 21:45:16 GMT-0800 (Pacific Standard Time)',
field: 125},
{ _id: 5dda1951f330d521a035c445,
date: 'Sat Nov 23 2019 21:46:57 GMT-0800 (Pacific Standard Time)',
field: '111' } ]
You could do something like this.
In Node section
res.status(200).send(stringifyMongoDBCollection(user_data_collection));
Client side
function getContent() {
$.ajax({
url: "https://jsonplaceholder.typicode.com/todos",
success: function (res) {
if (res) {
res = res.slice(0, 5); // limiting data to 5
var val = '';
res.forEach(todo => {
val += '<p><b>Title:</b>' + todo.title + ' <b>Completed:</b> ' + todo.completed + '</p>';
});
}
$("#content").html(val);
},
error: function () {
var val = '<p>Error in loading content</p>'
$("#content").html(val);
}
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button onclick="getContent()">Get Content</button>
<h1>Todo</h1>
<div id="content"></div>
References
jQuery ajax() Method
Node.js - Response Object
AJAX Introduction
I am trying to get JSON data from REST displaying on a web page using javascript
I have the following REST call working fine to the firefox console
function gethosts() {
var xhttp = new XMLHttpRequest();
xhttp.open("GET", "https://10.10.10.10/api/machine", false);
xhttp.setRequestHeader("Content-type", "application/json");
xhttp.send();
var response = JSON.parse(xhttp.responseText);
}
The JSON data is the following,
{
"offset": 0,
"hosts": [
{
"id": "422022c0-4ca7-66a2-bf73-9b56a65c9d2f",
"name": "System Z",
"type": "ORIGINAL",
"model": "System X",
"version": "Release 01",
"management_ip": "10.10.10.11",
"state": "ALIVE",
"date": "2017-01-05T17:55:58Z"
},
I want this displayed using html
Name: System Z
Model: System X
Version: Release 01
MGMT IP: 10.10.10.11
State: ALIVE
I tried adding this to the function but it doesn't seem to work
obj.hosts[0].name// return name
obj.hosts[0].model // return model
$( "body" ).append("<div>"+obj.hosts[0].name+"</div>")
$( "body" ).append("<div>"+obj.hosts[0].model+"</div>")
The sample HTML code is,
<button type="button" onclick="gethosts()">Get all Hosts</button>
<div id="gethosts">Hosts: </div>
Where did obj come from? response is the parsed JSON.
function gethosts() {
var xhttp = new XMLHttpRequest();
xhttp.open("GET", "https://10.10.10.10/api/machine", false);
xhttp.setRequestHeader("Content-type", "application/json");
xhttp.send();
var response = JSON.parse(xhttp.responseText);
$("body").append("<div>"+response.hosts[0].name+"</div>")
$("body").append("<div>"+response.hosts[0].model+"</div>")
}
Also, why the mix of vanilla JS and jQuery? Why not use $.ajax if you already have jQuery loaded?
I am working with Meteor.js. I need place photos of google place. I am working with Javascript here. So here is what I've done.
Meteor.call('getPlaceDetails', result.place_id, function (error, placeDetailsResult) {
if (error) {
console.log(error);
} else {
console.log(placeDetailsResult.data.result.photos[0].photo_reference);
Meteor.call('getPlacePhotos', placeDetailsResult.data.result.photos[0].photo_reference, function (error, photoresult) {
if (error) {
console.log(error);
} else {
console.log(photoresult);
}
});
}
});
I successfully got place_id from Place Details API call. With place_id I can then again successfully call the Place Photos API. I think all goes well here. In response I should get the photo and this is my responded JSON object:
Object {statusCode: 200, content: "����JFIF��*ExifII*1…!�o~Ç����`��&]<sP�\U��TV-���##�{��8�#7��*�"���", headers: Object, data: null}
content
:
"����JFIF��*ExifII*1Google���↵ ↵↵↵↵↵
data
:
null
headers
:
Object
access-control-allow-origin
:
"*"
access-control-expose-headers
:
"Content-Length"
alt-svc
:
"quic=":443"; ma=2592000; v="36,35,34,33,32,31,30""
alternate-protocol
:
"443:quic"
cache-control
:
"public, max-age=86400, no-transform"
connection
:
"close"
content-disposition
:
"inline;filename="2015-11-13.jpg""
content-length
:
"38587"
content-type
:
"image/jpeg"
date
:
"Thu, 01 Sep 2016 12:12:47 GMT"
etag
:
""v21fad""
expires
:
"Fri, 02 Sep 2016 12:12:47 GMT"
server
:
"fife"
vary
:
"Origin"
x-content-type-options
:
"nosniff"
x-xss-protection
:
"1; mode=block"
__proto__
:
Object
statusCode
:
200
__proto__
:
Object
In the documentation here: https://developers.google.com/places/web-service/photos they say you get a photo in return. So everything is fine, but I don't know how to display this photo on my website according there is no url. Please provide some usefull info.
Thanks :)
I did miss that function of what Sorin Lascu has commented. If someone is doing that in Meteor.js I will provide a complete and easy answer. I created an input field which has Google Maps API autocomplete, and shows the place on a map instantly. You also get all the necessary data you need to show to photos and other details.
I added this package jeremy:geocomplete to my project.
I created a map in HTML like this:
<div class="col s12 m10 l10 push-m1 push-l1" id="google_mapPlace">
{{> googleMap name="mapPlace" options=mapOptions}}
</div>
I added an input field in HTML
<input value="" type="text" class="findPlace">
Then in my js file I update my function with autorun.
Template.adminCollections.onRendered(function() {
this.autorun(function () {
if (GoogleMaps.loaded()) {
$(".findPlace").geocomplete({
map: "#google_mapPlace",
nearbySearchKeys: ['photos', 'place_id', 'name', 'geometry']
}).bind("geocode:result", function(event, result){
$('.myimg').attr('src', result.photos[0].getUrl({'maxWidth': 500, 'maxHeight': 500}));
});
});
});
});
While requesting HTTP responses with Node.js and importing these into MongoDB, I noticed one or two URLs will have headers that contain illegal characters (since they are being used keys) which will crash the entire script as I try to import into MongoDB. An example is below:
{
"url": "divensurf.com",
"statusCode": 200,
"headers": {
"x-varnish": "2236710953 2236710300",
"vary": "Accept-Encoding,Cookie,X-UA-Device",
"cache-control": "max-age=7200, must-revalidate",
"x-cache": "V1HIT 2",
"content-type": "text/html; charset=UTF-8",
"page.ly": "v4.0",
"x-pingback": "http://divensurf.com/xmlrpc.php",
"date": "Thu, 21 Mar 2013 19:40:59 GMT",
"transfer-encoding": "chunked",
"via": "1.1 varnish",
"connection": "keep-alive",
"last-modified": "Thu, 21 Mar 2013 19:40:57 GMT",
"age": "2"
}
}
The header/key "page.ly" would crash the script, since it contains an illegal character .. Are there any ways to sanitize this key/header which is enclosed in a quote by removing these illegal characters before I import this document into MongoDB?
Below is the code in which I request responses:
(function (i){
http.get(options, function(res) {
var obj = {};
obj.url = hostNames[i];
obj.statusCode = res.statusCode;
obj.headers = res.headers;
db.scrape.save(obj); // imports headers into MongoDB
}).on('error',function(e){
console.log("Error: " + hostNames[i] + "\n" + e.stack); // prints error stack onto console
})
})(i);
For example, it would be from "page.ly" to "pagely"
EDIT: SOLVED. Check Gael's answer.
obj.headers={};
for(var item in res.headers){
obj.headers[ item.replace(/\./,'')] = res.headers[item];
}