Codeigniter Jquery Ajax request error on URL localhost - javascript

i'm using Codeigniter 3.11, php 7.4, and jquery 3.5.1. Recently, i create a rest API using restserver in Codeigniter. And this rest server will be hosted once finished. Below is the code for controller in the server:
<?php
defined('BASEPATH') or exit('No direct script access allowed');
require 'vendor/autoload.php';
use chriskacerguis\RestServer\RestController;
class Genre extends RestController
{
private const PATH_MODEL = 'Genre_model';
private const PARAM_CATEGORY = 'c';
private const PARAM_LIMIT = 'l';
private const PARAM_GROUPED = 'g';
private const PARAM_STATUS = 'status';
private const PARAM_MESSAGE = 'messages';
private const PARAM_RESULT = 'result';
private const STATUS_OK = 'ok';
private const STATUS_ERROR = 'error';
public function __construct()
{
parent::__construct();
$this->load->model($this::PATH_MODEL, 'genre');
}
public function index_get()
{
$limit = (isset($_GET[$this::PARAM_LIMIT])) ? (int) $_GET[$this::PARAM_LIMIT] : 0;
$isGrouped = (isset($_GET[$this::PARAM_GROUPED])) ? (int)($_GET[$this::PARAM_GROUPED]) : false;
$this->response(
array(
$this::PARAM_STATUS => $this::STATUS_OK,
$this::PARAM_MESSAGE => 'success get data.',
$this::PARAM_RESULT => $this->genre->getGenre($limit, $isGrouped)
),
RestController::HTTP_OK
);
}
}
?>
And this is the code for client:
$("#btn").on("click", function() {
var settings = {
"url": "localhost/local-api/v1/genre?g=1&l=5",
headers: {
'X-Requested-With': 'XMLHttpRequest'
},
"method": "GET",
"timeout": 0,
};
$.ajax(settings).done(function(response) {
console.log(response);
});
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="btn">Click me</button>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
</body>
</html>
I'm getting this error when i want to request to localhost using jquery ajax.
jquery-3.5.1.min.js:2 GET http://localhost/local-api/localhost/local-api/v1/genre?g=1&l=5 404 (Not Found)
Can anyone explain why the link get duplicated? and how to solve it? thank you for your interest.

Related

js async await fetch with cached approach

I have to add a list of data structures to a js object on an HTML page.
I have a list of data structures on the server side each identified by a data-key.
A js function loops the list of data-keys
the function gets each structure one at a time from a async_cache using the corresponding data-key.
There may be multiples of same data-keys in the list
if the async_cache doesn't have the data-structure by that data-key it async-fetches and adds it to the cache.
if the async_cache has the data-structure by that data-key it returns it right away.
if the async_cache has already requested a fetch for a data-key and before the data arrives has another request for the same data-key it must not duplicate the request but wait until the data arrives.
I have constructed the following code so far (as an example for discussion). The actual environment can't be shared.
<?php
switch($_GET['--action'] ?? false){
case 'data-structure':{
$data_group = [
'data-01' => ['a' => 'info-01', 'b' => 'extra-01'],
'data-02' => ['a' => 'info-02', 'b' => 'extra-02'],
'data-03' => ['a' => 'info-03', 'b' => 'extra-03'],
'data-04' => ['a' => 'info-04', 'b' => 'extra-04'],
'data-05' => ['a' => 'info-05', 'b' => 'extra-05'],
];
if($data_struct = ($data_group[$_GET['key'] ?? false] ?? false)){
\header('Content-Type: application/json');
echo json_encode(['status'=> 'ok', 'data' => $data_struct], JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
exit();
} else {
http_response_code(404);
echo json_encode('Not Found', JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
exit();
}
} break;
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta key="viewport" content="width=device-width, initial-scale=1.0">
<title>JS Async Data Buffer Experiment</title>
</head>
<body>
<div class="container">
</div>
<script>
xui = {};
xui.async_cache = {
async async_get_await(url = '', options = {}){
// Default options are marked with *
const response = await fetch(
url,
{
method: 'GET', // *GET, POST, PUT, DELETE, etc.
mode: options.mode || 'same-origin', // no-cors, *cors, same-origin
cache: options.cache || 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: options.credintials || 'same-origin', // include, *same-origin, omit
redirect: options.redirect || 'follow', // manual, *follow, error
referrerPolicy: options.referrerPolicy || 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
}
);
return response.json(); // parses JSON response into native JavaScript objects;
},
get(action, key){
if(key in this){
return new Promise((resolve, reject) => {
resolve(this[key]);
});
} else {
return this.async_get_await(
`?--action=${action}&key=${key}`,
).then((r) => {
this[key] = r.data;
return this[key];
});
}
},
};
window.addEventListener('DOMContentLoaded', function(){
var list = [
'data-01',
'data-01',
'data-02',
'data-01',
'data-03',
'data-02',
'data-04',
'data-02',
'data-01',
];
list.forEach((key) => {
console.log({key});
xui.async_cache.get('data-structure', key).then((data) => {
console.log(data);
});
});
});
</script>
</body>
</html>
Case 1 and 2 are taken care of but case 3 is where I am stuck. As you can see the code in the addEventListner executes in one shot before the data is received or event-loop kicks-in. So multiple requests go out for the same data-key.
I am looking for a minimalist approach. If there is a coding feature in JS library without using third party library - that will do as well.
I've also looked into the cache option on the Fetch-API but that is not a solution.
Thanks!
Thanks to #Bergi I finally figured it out!
I rewrote the async_cache and went on simplifying ...
Here is what I got (I've added a few test buttons as well):
<?php
switch($_GET['--action'] ?? false){
case 'data-structure':{
$data_group = [
'data-01' => ['a' => 'info-01', 'b' => 'extra-01'],
'data-02' => ['a' => 'info-02', 'b' => 'extra-02'],
'data-03' => ['a' => 'info-03', 'b' => 'extra-03'],
'data-04' => ['a' => 'info-04', 'b' => 'extra-04'],
'data-05' => ['a' => 'info-05', 'b' => 'extra-05'],
];
if($data_struct = ($data_group[$_GET['key'] ?? false] ?? false)){
\header('Content-Type: application/json');
echo json_encode(['status'=> 'ok', 'data' => $data_struct], JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
exit();
} else {
http_response_code(404);
echo json_encode('Not Found', JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
exit();
}
} break;
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta key="viewport" content="width=device-width, initial-scale=1.0">
<title>JS Async Data Cache Example</title>
</head>
<body>
<div class="container">
<button type="button" onclick="run()">Run</button> <br/>
<button type="button" onclick="delete xui.async_cache['data-01']">Delete 01</button> <br/>
<button type="button" onclick="delete xui.async_cache['data-02']">Delete 02</button> <br/>
<button type="button" onclick="delete xui.async_cache['data-03']">Delete 03</button> <br/>
<button type="button" onclick="delete xui.async_cache['data-04']">Delete 04</button> <br/>
Look at the console for responses and check the network tab as well!
</div>
<script>
xui = {};
xui.async_cache = {
get(key){
return this[key] ?? (this[key] = (fetch(`?--action=data-structure&key=${key}`).then((response) => {
return response.json();
})));
}
};
function run(){
var list = [
'data-01',
'data-01',
'data-02',
'data-01',
'data-03',
'data-02',
'data-04',
'data-02',
'data-01',
];
list.forEach((key) => {
console.log({key});
xui.async_cache.get(key).then((data) => {
console.log(data);
});
});
}
window.addEventListener('DOMContentLoaded', function(){
run();
});
</script>
</body>
</html>
Looks like we can take advantage of the closure's data storage (or caching) inside the promise. And we don't need await or async, atleast for this rudimentary stage.

firebase auth signInWithCustomToken method not working in iPhone

I am developing one PWA of the ionic capacitor and there is a requirement to load another website in an iframe so from one of the ionic app component I called another site.
iframe.page.html
<ion-header>
<ion-toolbar>
<ion-buttons slot="end" (click)="goBack()">
Close
<ion-icon slot="icon-only" name="close-outline"></ion-icon>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content>
<iframe #iframe height="100%" width="100%" title="test"></iframe>
</ion-content>
iframe.page.ts
export class IframePage implements OnInit, AfterViewInit {
userId = localStorage.getItem('userId');
gameData: any;
gameUrl: any;
docId;
#ViewChild('iframe') iframe: ElementRef;
constructor(private navCtrl: NavController,
private authSrv: AuthService,
private commanSrv: CommannService,
private router:Router) {
firebase.analytics().logEvent('Web_game');
this.iframe.nativeElement.setAttribute('src', 'anotherdomain.com?UID=sadsajdhsakjhdasjhkjsd');
window.addEventListener('message', (event) => {
console.log(event.data);
if (event.data.res === 'win') {
// let routename = commanSrv.getLastRoute();
// navCtrl.navigateForward(routename || 'home_tab');
this.router.navigate(['arcade-outcome', { type: 'arcade_win' }]);
} else if (event.data.res === 'loss'){
this.router.navigate(['arcade-outcome', { type: 'arcade_lose' }]);
} else {
// if (event.data === 'closed') {
let routename = commanSrv.getLastRoute();
navCtrl.navigateBack(routename || 'home_tab');
// }
}
});
}
}
And now
another site is made up of HTML and javascript and here is code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/png" href="assets/icon/favicon.png" />
<link rel="stylesheet" type="text/css" href="./assets/css/custom.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.4.3/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.4.3/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.4.3/firebase-firestore.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.4.3/firebase-database.js"></script>
<script src="scripts/firebase.js"></script>
<script type="text/javascript" src="scripts/index.js"></script>
<title>HTML 5 game application</title>
</head>
<body>
<p>Loader screen</p>
<div class="loader"></div>
<script>
$(document).ready(function(){
const serverUrl = 'https://us-central1-domain.cloudfunctions.net/';
var token;
var xhttp = new XMLHttpRequest();
var gamePlayData;
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
const userId = urlParams.get('UID')
const gamePlay = urlParams.get('gameplay')
const mode = urlParams.get('mode')
function getUserDetails(token) {
console.log("getUserDetails start token ", token);
console.log(firebase);
firebase.auth().signInWithCustomToken(token).then((userCredential) => { // execution stop from here.
console.log("getUserDetails end");
var user = userCredential.user;
if (user !== null) {
window.location.replace(`anotherdomain.com/start.html?id=${userId}&gamePlay=${gamePlay}`);
}
})
.catch((error) => {
console.log('error in catch: ', error);
var errorCode = error.code;
var errorMessage = error.message;
// window.history.back();
alert('User is not logged in.')
// parent.postMessage('closed', '*');
});
}
function checkAuth() {
console.log("ajax call start");
$.ajax({
type: "POST",
url: serverUrl + 'checkAuthStatus',
data: { uid: userId },
success: function (response) {
console.log("ajax call end");
//if request if made successfully then the response represent the data
getUserDetails(response.result);
},
error: function (err) {
console.log(err);
}
});
}
checkAuth();
});
</script>
From the line
firebase.auth().signInWithCustomToken(token).then(() => {
Execution cancelled and iframe got closed , window.addEventListener('message', (event) => { got called navigated to ionic application back.
The surprising is, this issue only occurs in iPhone whereas for android it is working fine.
When navigating to another domain site 3rd time then it working and got the success in firebase.auth().signInWithCustomToken(token).then((userCredential) => { .
Please help me.

Why is my fetch request not executing inside an event listener callback function?

Just getting the hang of API calls and fetch and have put together the below code to fetch some info from the Trip Advisor API and log a message to the console using this info.
When I call the fetch request function it logs to the console just fine, but as soon as I wrap it in an event listener callback it no longer executes, why is this?
Appreciate any help!
//This is the fetch function kept in a file names request.js
const findRest = async (reviews, closed) => {
const respond = await fetch(
"https://tripadvisor1.p.rapidapi.com/restaurants/list-by-latlng?limit=30&currency=EUR&distance=2&lunit=km&lang=en_US&latitude=53.3498&longitude=-6.2603",
{
method: "GET",
headers: {
"x-rapidapi-host": "tripadvisor1.p.rapidapi.com",
"x-rapidapi-key": /* my rapidapi key */
}
}
);
if (respond.status === 200) {
let data = await respond.json();
let newData = await data.data;
let data1 = await newData.filter(
review => parseInt(review.num_reviews) >= reviews
);
let data2 = await data1.filter(close => close.is_closed == closed);
return data2;
} else {
throw new Error("Could not provide results within specified parameters");
}
};
//This is the event listener kept in a file names app.js - both files are active and no problems communicating with each other
document.querySelector(".subButton").addEventListener("click", e => {
e.preventDefault();
console.log("click");
const userReviews = parseInt(document.querySelector(".userRev").value);
const userClose = document.querySelector(".userClose").value;
findRest(userReviews, userClose)
.then(data => {
data.forEach(element => {
console.log(
`${element.name} matches your search criterea and is located at ${element.address}
To make a booking, please call ${element.phone}`
);
});
})
.catch(err => {
console.log(err);
});
});
//HTML below
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>What Wine?</title>
<meta name="author" content="Phil My Glass" />
<meta
name="description"
content="An app to help you find the wine you like or something new based on your preferences"
/>
<meta name="keywords" content="wine" />
<link rel="stylesheet" href="style.css" type="text/css" />
</head>
<body>
<header>
<h1>What Restaurant?</h1>
</header>
<main>
<form>
<input class="userRev" /><br />
<input class="userClose" />
<button class="subButton" type="submit">Find!</button>
</form>
</main>
</body>
<script src="req.js" type="text/Javascript"></script>
<script src="app.js" type="text/Javascript"></script>
</html>
Those two lines look like they could break the thread:
const userReviews = parseInt(document.querySelector(".userRev").value);
const userClose = document.querySelector(".userClose").value;
If either one of document.querySelector(".userRev"), document.querySelector(".userClose") is null, that will be uncaught TypeError.
Will know for sure with the HTML.

how to disable Cache in a REST Tree in DOJO with a complete code to reproduce it

The following code shows a tree in Dojo using dojox.data.JsonRestStore with one node named Changing0 with children to be lazy loaded. the problem is in updating the tree by renaming the one node (Changing1, Changing2,...) without changing its reference number or id.
The question is the following: if it is a caching problem, how to disable caching.
Please note that on the log file we can see that the REST is functioning well but the name is unchanged on the tree. Even if we use refresh2() instead of refresh1() by deleting the whole tree and its data and recreating it. Maybe it is the $ref that is kept in javascript referencing since we do not change the id.
the code is the following:
reproducing_problem.php:
<?php
if(!isset($_SESSION))
{
session_start();
}
$_SESSION['keyA']=0;
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Reproducing Cache Problem</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<!--META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE"-->
<script type="text/javascript" src="../external/dojo/dojo.js" djConfig="parseOnLoad: true"></script>
<script type="text/javascript">
dojo.require('dojox.data.JsonRestStore');
dojo.require('dijit.Tree');
dojo.require("dijit.form.Button");
var prod= {
store: null,
model: null,
tree: null,
init: function() {
this.store = new dojox.data.JsonRestStore({
target: 'reproducing-REST.php',
labelAttribute: "name"
});
this.model = new dijit.tree.ForestStoreModel({
store: this.store,
deferItemLoadingUntilExpand: true,
rootId: "products",
rootLabel: "Products",
query: {queryOptions:{cache:false}},
childrenAttrs: ['children']
});
}
};
function refresh1() {
tree=prod.tree
tree._itemNodesMap = {};
tree.rootNode.state = "UNCHECKED";
tree.model.root.children = null;
if (tree.rootNode) {
tree.rootNode.destroyRecursive();
}
tree._load();
}
function refresh2() {
delete prod.tree;
delete prod.model;
delete prod.store;
dijit.byId('products_tree').destroy(true);
prod.init();
prod.tree = new dijit.Tree({
model: prod.model,
query: {queryOptions:{preventCache:true}},
persist: false
}, 'products_tree');
prod.tree.startup();
}
dojo.addOnLoad(function() {
prod.init();
//prod.store.fetch({queryOptions:{cache:false}});
prod.tree = new dijit.Tree({
model: prod.model,
//query: {queryOptions:{cache:false}},
persist: false
}, 'products_tree');
prod.tree.startup();
});
</script>
<style type="text/css">
#import "../external/dijit/themes/soria/soria.css";
#import "../external/dojo/resources/dojo.css";
</style>
</head>
<body class="soria">
<div dojoType="dijit.form.Button">
Change name and refresh
<script type="dojo/event" event="onClick">
refresh1();
</script>
</div>
<div id="products_tree"></div>
<div id="notes">notes</div>
</body>
</html>
reproducing-REST.php:
<?php
if(!isset($_SESSION))
{
session_start();
}
$keyA=$_SESSION['keyA'];
$_SESSION['keyA']=$keyA+1;
if (array_key_exists('PATH_INFO', $_SERVER)) {
$arr = null;
$resource = $_SERVER['PATH_INFO'];
$method = $_SERVER['REQUEST_METHOD'];
error_log(" resource: ".$resource." \n",3,"mylogfile.txt");
if ($method == 'GET') {
if ($resource=='/'){
$arr=array();
$sameref='1234';
$name="Changing".$keyA;
error_log(" name: ".$name." \n",3,"mylogfile.txt");
array_push($arr,array('$ref' => $sameref, 'name' => $name, 'children' => true));
}
else{
$aProduct = ltrim($resource, '/');
$arr=array();
$name="exploding";
$child='2345';
array_push($arr,array('name' => $name,'idq' => $child));
$arr=array('idp' => $aProduct, 'name' => $name, 'children' => $arr);
}
$status = 'HTTP/1.1 200 OK';
}
header($status);
echo json_encode($arr);
}
?>
thank you

Converting base64 String to JSON String and Sent to REST API using javascript

I am using AngularJS, HTML 5, JavaScript and Rest API to upload an image in database.
The back-end is made on Hibernate and it is working perfectly.
The image is being converted to base64 String and then it is being send to Rest API.
The problem is that the image is being uploaded in the database but there is an error showing in the console.
Here is he code
HTML Code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Home</title>
<link rel="stylesheet"
href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="http://www.w3schools.com/lib/w3.css">
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script
src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script
src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/angular-base64/2.0.5/angular-base64.js"></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/angular-base64/2.0.5/angular-base64.min.js"></script>
<script type="text/javascript"
src="https://cdn.rawgit.com/adonespitogo/angular-base64-upload/master/src/angular-base64-upload.js"></script>
</head>
<body ng-app="pic" ng-controller="MainController">
<input type="file" ng-model="image" base-sixty-four-input>
<button ng-click="upload()">Upload</button>
<div ng-bind="message"></div>
<script type="text/javascript" src="main.js"></script>
</body>
</html>
Main JS File
URI = "http://localhost:8085/PictureUpload/api/";
var app = angular.module('pic', [ 'naif.base64' ])
app.controller("MainController", [ '$scope', '$http', function($scope, $http) {
$scope.image = {};
$scope.upload = function() {
try {
var data = angular.toJson($scope.image.base64);
console.log(data)
var responsePromise = $http.post(URI + "PictureAPI",data);
} catch (err) {
$scope.message = "There is some system Issue, Please contact Administrator";
}
responsePromise.success(function(dataFromServer,
status, headers, config) {
$scope.message=dataFromServer;
console.log($scope.message)
});
responsePromise.error(function(data, status, headers,
config) {
});
}
} ])
API File
package com.pic.API;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.apache.tomcat.util.codec.binary.Base64;
import com.google.gson.Gson;
import com.pic.DAO.PictureDAO;
import com.pic.resources.AppConfig;
#Path("/PictureAPI")
public class PictureAPI {
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Response saveImage(String dataRecieved) {
System.out.println(dataRecieved);
Gson gson = new Gson();
Response returnValue = null;
byte[] image = Base64.decodeBase64(dataRecieved);
System.out.println(image);
PictureDAO pd = new PictureDAO();
try {
pd.savePicture(image);
String value = "Photo Uploaded";
returnValue = Response.ok(value).build();
} catch (Exception e) {
String message = AppConfig.PROPERTIES.getProperty(e.getMessage());
String value = gson.toJson(message);
if (e.getMessage().contains("DAO")) {
returnValue = Response.status(Status.SERVICE_UNAVAILABLE)
.entity(value).build();
} else {
returnValue = Response.status(Status.BAD_REQUEST).entity(value)
.build();
}
}
return returnValue;
}
}
Error in Console.
angular.js:13642 SyntaxError: Unexpected token P in JSON at position 0
at wc (angular.js:1352)
at dc (angular.js:10455)
at angular.js:10546
at q (angular.js:322)
at gd (angular.js:10545)
at c (angular.js:11343)
at angular.js:16104
at m.$eval (angular.js:17378)
at m.$digest (angular.js:17191)
at m.$apply (angular.js:17486)

Categories